diff --git a/Android.mk b/Android.mk deleted file mode 100644 index 8b79cebad572d002cc6469106be83aede922a35e..0000000000000000000000000000000000000000 --- a/Android.mk +++ /dev/null @@ -1,29 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(my-dir) - -ifneq ($(TARGET_SIMULATOR),true) - include $(call first-makefiles-under,$(LOCAL_PATH)) -else - include $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ - adb \ - libcutils \ - liblog \ - libnetutils \ - libpixelflinger \ - libzipfile \ - )) -endif diff --git a/README b/README deleted file mode 100644 index 0083247acfa4973bb5e5375dd009114c578353e5..0000000000000000000000000000000000000000 --- a/README +++ /dev/null @@ -1,20 +0,0 @@ - -The system/ directory is intended for pieces of the world that are the -core of the embedded linux platform at the heart of Android. These -essential bits are required for basic booting, operation, and debugging. - -They should not depend on libraries outside of system/... (some of them -do currently -- they need to be updated or changed) and they should not -be required for the simulator build. - -The license for all these pieces should be clean (Apache2, BSD, or MIT). - -Currently system/bluetooth/... and system/extra/... have some pieces -with GPL/LGPL licensed code. - -Assorted Issues: - -- pppd depends on libutils for logging -- pppd depends on libcrypt/libcrypto -- init, linker, debuggerd, toolbox, usbd depend on libcutils -- should probably rename bionic to libc diff --git a/adb/Android.mk b/adb/Android.mk deleted file mode 100644 index 2296610a3380ba1c48546d1cb081bb01962a3085..0000000000000000000000000000000000000000 --- a/adb/Android.mk +++ /dev/null @@ -1,140 +0,0 @@ -# Copyright 2005 The Android Open Source Project -# -# Android.mk for adb -# - -LOCAL_PATH:= $(call my-dir) - -# adb host tool -# ========================================================= -ifneq ($(TARGET_SIMULATOR),true) # not 64 bit clean (also unused with the sim) -include $(CLEAR_VARS) - -# Default to a virtual (sockets) usb interface -USB_SRCS := -EXTRA_SRCS := - -ifeq ($(HOST_OS),linux) - USB_SRCS := usb_linux.c - EXTRA_SRCS := get_my_path_linux.c - LOCAL_LDLIBS += -lrt -lncurses -lpthread -endif - -ifeq ($(HOST_OS),darwin) - USB_SRCS := usb_osx.c - EXTRA_SRCS := get_my_path_darwin.c - LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon -endif - -ifeq ($(HOST_OS),windows) - USB_SRCS := usb_windows.c - EXTRA_SRCS := get_my_path_windows.c - EXTRA_STATIC_LIBS := AdbWinApi - LOCAL_C_INCLUDES += /usr/include/w32api/ddk development/host/windows/usb/api/ - ifneq ($(strip $(USE_CYGWIN)),) - LOCAL_LDLIBS += -lpthread - else - LOCAL_LDLIBS += -lws2_32 - USE_SYSDEPS_WIN32 := 1 - endif -endif - -LOCAL_SRC_FILES := \ - adb.c \ - console.c \ - transport.c \ - transport_local.c \ - transport_usb.c \ - commandline.c \ - adb_client.c \ - sockets.c \ - services.c \ - file_sync_client.c \ - $(EXTRA_SRCS) \ - $(USB_SRCS) \ - shlist.c \ - utils.c \ - - -ifneq ($(USE_SYSDEPS_WIN32),) - LOCAL_SRC_FILES += sysdeps_win32.c -endif - -LOCAL_CFLAGS += -O2 -g -DADB_HOST=1 -Wall -Wno-unused-parameter -LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE -DSH_HISTORY -LOCAL_MODULE := adb - -LOCAL_STATIC_LIBRARIES := libzipfile libunz $(EXTRA_STATIC_LIBS) -ifeq ($(USE_SYSDEPS_WIN32),) - LOCAL_STATIC_LIBRARIES += libcutils -endif - -include $(BUILD_HOST_EXECUTABLE) - -$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) - -ifeq ($(HOST_OS),windows) -$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll -endif - -endif - -# adbd device daemon -# ========================================================= - -# build adbd in all non-simulator builds -BUILD_ADBD := false -ifneq ($(TARGET_SIMULATOR),true) - BUILD_ADBD := true -endif - -# build adbd for the Linux simulator build -# so we can use it to test the adb USB gadget driver on x86 -ifeq ($(HOST_OS),linux) - BUILD_ADBD := true -endif - - -ifeq ($(BUILD_ADBD),true) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - adb.c \ - transport.c \ - transport_local.c \ - transport_usb.c \ - sockets.c \ - services.c \ - file_sync_service.c \ - jdwp_service.c \ - framebuffer_service.c \ - remount_service.c \ - usb_linux_client.c \ - log_service.c \ - utils.c \ - -LOCAL_CFLAGS := -O2 -g -DADB_HOST=0 -Wall -Wno-unused-parameter -LOCAL_CFLAGS += -D_XOPEN_SOURCE -D_GNU_SOURCE - -# TODO: This should probably be board specific, whether or not the kernel has -# the gadget driver; rather than relying on the architecture type. -ifeq ($(TARGET_ARCH),arm) -LOCAL_CFLAGS += -DANDROID_GADGET=1 -endif - -LOCAL_MODULE := adbd - -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN) -LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED) - -ifeq ($(TARGET_SIMULATOR),true) - LOCAL_STATIC_LIBRARIES := libcutils - LOCAL_LDLIBS += -lpthread - include $(BUILD_HOST_EXECUTABLE) -else - LOCAL_STATIC_LIBRARIES := libcutils libc - include $(BUILD_EXECUTABLE) -endif - -endif diff --git a/adb/OVERVIEW.TXT b/adb/OVERVIEW.TXT deleted file mode 100644 index 6a5191aeeff4219499ba72f88685928ecc7667c8..0000000000000000000000000000000000000000 --- a/adb/OVERVIEW.TXT +++ /dev/null @@ -1,139 +0,0 @@ -Implementation notes regarding ADB. - -I. General Overview: - -The Android Debug Bridge (ADB) is used to: - -- keep track of all Android devices and emulators instances - connected to or running on a given host developer machine - -- implement various control commands (e.g. "adb shell", "adb pull", etc..) - for the benefit of clients (command-line users, or helper programs like - DDMS). These commands are what is called a 'service' in ADB. - -As a whole, everything works through the following components: - - 1. The ADB server - - This is a background process that runs on the host machine. Its purpose - if to sense the USB ports to know when devices are attached/removed, - as well as when emulator instances start/stop. - - It thus maintains a list of "connected devices" and assigns a 'state' - to each one of them: OFFLINE, BOOTLOADER, RECOVERY or ONLINE (more on - this below). - - The ADB server is really one giant multiplexing loop whose purpose is - to orchestrate the exchange of data (packets, really) between clients, - services and devices. - - - 2. The ADB daemon (adbd) - - The 'adbd' program runs as a background process within an Android device - or emulated system. Its purpose is to connect to the ADB server - (through USB for devices, through TCP for emulators) and provide a - few services for clients that run on the host. - - The ADB server considers that a device is ONLINE when it has succesfully - connected to the adbd program within it. Otherwise, the device is OFFLINE, - meaning that the ADB server detected a new device/emulator, but could not - connect to the adbd daemon. - - the BOOTLOADER and RECOVERY states correspond to alternate states of - devices when they are in the bootloader or recovery mode. - - 3. The ADB command-line client - - The 'adb' command-line program is used to run adb commands from a shell - or a script. It first tries to locate the ADB server on the host machine, - and will start one automatically if none is found. - - then, the client sends its service requests to the ADB server. It doesn't - need to know. - - Currently, a single 'adb' binary is used for both the server and client. - this makes distribution and starting the server easier. - - - 4. Services - - There are essentially two kinds of services that a client can talk to. - - Host Services: - these services run within the ADB Server and thus do not need to - communicate with a device at all. A typical example is "adb devices" - which is used to return the list of currently known devices and their - state. They are a few couple other services though. - - Local Services: - these services either run within the adbd daemon, or are started by - it on the device. The ADB server is used to multiplex streams - between the client and the service running in adbd. In this case - its role is to initiate the connection, then of being a pass-through - for the data. - - -II. Protocol details: - - 1. Client <-> Server protocol: - - This details the protocol used between ADB clients and the ADB - server itself. The ADB server listens on TCP:localhost:5037. - - A client sends a request using the following format: - - 1. A 4-byte hexadecimal string giving the length of the payload - 2. Followed by the payload itself. - - For example, to query the ADB server for its internal version number, - the client will do the following: - - 1. Connect to tcp:localhost:5037 - 2. Send the string "000Chost:version" to the corresponding socket - - The 'host:' prefix is used to indicate that the request is addressed - to the server itself (we will talk about other kinds of requests later). - The content length is encoded in ASCII for easier debugging. - - The server should answer a request with one of the following: - - 1. For success, the 4-byte "OKAY" string - - 2. For failure, the 4-byte "FAIL" string, followed by a - 4-byte hex length, followed by a string giving the reason - for failure. - - 3. As a special exception, for 'host:version', a 4-byte - hex string corresponding to the server's internal version number - - Note that the connection is still alive after an OKAY, which allows the - client to make other requests. But in certain cases, an OKAY will even - change the state of the connection. - - For example, the case of the 'host:transport:<serialnumber>' request, - where '<serialnumber>' is used to identify a given device/emulator; after - the "OKAY" answer, all further requests made by the client will go - directly to the corresponding adbd daemon. - - The file SERVICES.TXT lists all services currently implemented by ADB. - - - 2. Transports: - - An ADB transport models a connection between the ADB server and one device - or emulator. There are currently two kinds of transports: - - - USB transports, for physical devices through USB - - - Local transports, for emulators running on the host, connected to - the server through TCP - - In theory, it should be possible to write a local transport that proxies - a connection between an ADB server and a device/emulator connected to/ - running on another machine. This hasn't been done yet though. - - Each transport can carry one or more multiplexed streams between clients - and the device/emulator they point to. The ADB server must handle - unexpected transport disconnections (e.g. when a device is physically - unplugged) properly. diff --git a/adb/SERVICES.TXT b/adb/SERVICES.TXT deleted file mode 100644 index b0124a4da70f9b20ba8004cd2647dcfe55789ec4..0000000000000000000000000000000000000000 --- a/adb/SERVICES.TXT +++ /dev/null @@ -1,236 +0,0 @@ -This file tries to document all requests a client can make -to the ADB server of an adbd daemon. See the OVERVIEW.TXT document -to understand what's going on here. - -HOST SERVICES: - -host:version - Ask the ADB server for its internal version number. - - As a special exception, the server will respond with a 4-byte - hex string corresponding to its internal version number, without - any OKAY or FAIL. - -host:kill - Ask the ADB server to quit immediately. This is used when the - ADB client detects that an obsolete server is running after an - upgrade. - -host:devices - Ask to return the list of available Android devices and their - state. After the OKAY, this is followed by a 4-byte hex len, - and a string that will be dumped as-is by the client, then - the connection is closed - -host:track-devices - This is a variant of host:devices which doesn't close the - connection. Instead, a new device list description is sent - each time a device is added/removed or the state of a given - device changes (hex4 + content). This allows tools like DDMS - to track the state of connected devices in real-time without - polling the server repeatedly. - -host:emulator:<port> - This is a special query that is sent to the ADB server when a - new emulator starts up. <port> is a decimal number corresponding - to the emulator's ADB control port, i.e. the TCP port that the - emulator will forward automatically to the adbd daemon running - in the emulator system. - - This mechanism allows the ADB server to know when new emulator - instances start. - -host:transport:<serial-number> - Ask to switch the connection to the device/emulator identified by - <serial-number>. After the OKAY response, every client request will - be sent directly to the adbd daemon running on the device. - (Used to implement the -s option) - -host:transport-usb - Ask to switch the connection to one device connected through USB - to the host machine. This will fail if there are more than one such - devices. (Used to implement the -d convenience option) - -host:transport-local - Ask to switch the connection to one emulator connected through TCP. - This will fail if there is more than one such emulator instance - running. (Used to implement the -e convenience option) - -host:transport-any - Another host:transport variant. Ask to switch the connection to - either the device or emulator connect to/running on the host. - Will fail if there is more than one such device/emulator available. - (Used when neither -s, -d or -e are provided) - -host-serial:<serial-number>:<request> - This is a special form of query, where the 'host-serial:<serial-number>:' - prefix can be used to indicate that the client is asking the ADB server - for information related to a specific device. <request> can be in one - of the format described below. - -host-usb:<request> - A variant of host-serial used to target the single USB device connected - to the host. This will fail if there is none or more than one. - -host-local:<request> - A variant of host-serial used to target the single emulator instance - running on the host. This will fail if therre is none or more than one. - -host:<request> - When asking for information related to a device, 'host:' can also be - interpreted as 'any single device or emulator connected to/running on - the host'. - -<host-prefix>:get-product - XXX - -<host-prefix>:get-serialno - Returns the serial number of the corresponding device/emulator. - Note that emulator serial numbers are of the form "emulator-5554" - -<host-prefix>:get-state - Returns the state of a given device as a string. - -<host-prefix>:forward:<local>;<remote> - Asks the ADB server to forward local connections from <local> - to the <remote> address on a given device. - - There, <host-prefix> can be one of the - host-serial/host-usb/host-local/host prefixes as described previously - and indicates which device/emulator to target. - - the format of <local> is one of: - - tcp:<port> -> TCP connection on localhost:<port> - local:<path> -> Unix local domain socket on <path> - - the format of <remote> is one of: - - tcp:<port> -> TCP localhost:<port> on device - local:<path> -> Unix local domain socket on device - jdwp:<pid> -> JDWP thread on VM process <pid> - - or even any one of the local services described below. - - - -LOCAL SERVICES: - -All the queries below assumed that you already switched the transport -to a real device, or that you have used a query prefix as described -above. - -shell:command arg1 arg2 ... - Run 'command arg1 arg2 ...' in a shell on the device, and return - its output and error streams. Note that arguments must be separated - by spaces. If an argument contains a space, it must be quoted with - double-quotes. Arguments cannot contain double quotes or things - will go very wrong. - - Note that this is the non-interactive version of "adb shell" - -shell: - Start an interactive shell session on the device. Redirect - stdin/stdout/stderr as appropriate. Note that the ADB server uses - this to implement "adb shell", but will also cook the input before - sending it to the device (see interactive_shell() in commandline.c) - -remount: - Ask adbd to remount the device's filesystem in read-write mode, - instead of read-only. This is usually necessary before performing - an "adb sync" or "adb push" request. - - This request may not succeed on certain builds which do not allow - that. - -dev:<path> - Opens a device file and connects the client directly to it for - read/write purposes. Useful for debugging, but may require special - priviledges and thus may not run on all devices. <path> is a full - path from the root of the filesystem. - -tcp:<port> - Tries to connect to tcp port <port> on localhost. - -tcp:<port>:<server-name> - Tries to connect to tcp port <port> on machine <server-name> from - the device. This can be useful to debug some networking/proxy - issues that can only be revealed on the device itself. - -local:<path> - Tries to connect to a Unix domain socket <path> on the device - -localreserved:<path> -localabstract:<path> -localfilesystem:<path> - Variants of local:<path> that are used to access other Android - socket namespaces. - -log:<name> - Opens one of the system logs (/dev/log/<name>) and allows the client - to read them directly. Used to implement 'adb logcat'. The stream - will be read-only for the client. - -framebuffer: - This service is used to send snapshots of the framebuffer to a client. - It requires sufficient priviledges but works as follow: - - After the OKAY, the service sends 16-byte binary structure - containing the following fields (little-endian format): - - depth: uint32_t: framebuffer depth - size: uint32_t: framebuffer size in bytes - width: uint32_t: framebuffer width in pixels - height: uint32_t: framebuffer height in pixels - - With the current implementation, depth is always 16, and - size is always width*height*2 - - Then, each time the client wants a snapshot, it should send - one byte through the channel, which will trigger the service - to send it 'size' bytes of framebuffer data. - - If the adbd daemon doesn't have sufficient priviledges to open - the framebuffer device, the connection is simply closed immediately. - -dns:<server-name> - This service is an exception because it only runs within the ADB server. - It is used to implement USB networking, i.e. to provide a network connection - to the device through the host machine (note: this is the exact opposite of - network thetering). - - It is used to perform a gethostbyname(<address>) on the host and return - the corresponding IP address as a 4-byte string. - -recover:<size> - This service is used to upload a recovery image to the device. <size> - must be a number corresponding to the size of the file. The service works - by: - - - creating a file named /tmp/update - - reading 'size' bytes from the client and writing them to /tmp/update - - when everything is read succesfully, create a file named /tmp/update.start - - This service can only work when the device is in recovery mode. Otherwise, - the /tmp directory doesn't exist and the connection will be closed immediately. - -jdwp:<pid> - Connects to the JDWP thread running in the VM of process <pid>. - -track-jdwp - This is used to send the list of JDWP pids periodically to the client. - The format of the returned data is the following: - - <hex4>: the length of all content as a 4-char hexadecimal string - <content>: a series of ASCII lines of the following format: - <pid> "\n" - - This service is used by DDMS to know which debuggable processes are running - on the device/emulator. - - Note that there is no single-shot service to retrieve the list only once. - -sync: - This starts the file synchronisation service, used to implement "adb push" - and "adb pull". Since this service is pretty complex, it will be detailed - in a companion document named SYNC.TXT diff --git a/adb/adb.c b/adb/adb.c deleted file mode 100644 index fa5269f5037c652a32954596aa90ab7ce9c73d9b..0000000000000000000000000000000000000000 --- a/adb/adb.c +++ /dev/null @@ -1,1083 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define TRACE_TAG TRACE_ADB - -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <stdarg.h> -#include <errno.h> -#include <string.h> -#include <time.h> - -#include "sysdeps.h" -#include "adb.h" - -#if !ADB_HOST -#include <private/android_filesystem_config.h> -#endif - - -int HOST = 0; - -static const char *adb_device_banner = "device"; - -void fatal(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "error: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(-1); -} - -void fatal_errno(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "error: %s: ", strerror(errno)); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(-1); -} - -int adb_trace_mask; - -/* read a comma/space/colum/semi-column separated list of tags - * from the ADB_TRACE environment variable and build the trace - * mask from it. note that '1' and 'all' are special cases to - * enable all tracing - */ -void adb_trace_init(void) -{ - const char* p = getenv("ADB_TRACE"); - const char* q; - - static const struct { - const char* tag; - int flag; - } tags[] = { - { "1", 0 }, - { "all", 0 }, - { "adb", TRACE_ADB }, - { "sockets", TRACE_SOCKETS }, - { "packets", TRACE_PACKETS }, - { "rwx", TRACE_RWX }, - { "usb", TRACE_USB }, - { "sync", TRACE_SYNC }, - { "sysdeps", TRACE_SYSDEPS }, - { "transport", TRACE_TRANSPORT }, - { "jdwp", TRACE_JDWP }, - { NULL, 0 } - }; - - if (p == NULL) - return; - - /* use a comma/column/semi-colum/space separated list */ - while (*p) { - int len, tagn; - - q = strpbrk(p, " ,:;"); - if (q == NULL) { - q = p + strlen(p); - } - len = q - p; - - for (tagn = 0; tags[tagn].tag != NULL; tagn++) - { - int taglen = strlen(tags[tagn].tag); - - if (len == taglen && !memcmp(tags[tagn].tag, p, len) ) - { - int flag = tags[tagn].flag; - if (flag == 0) { - adb_trace_mask = ~0; - return; - } - adb_trace_mask |= (1 << flag); - break; - } - } - p = q; - if (*p) - p++; - } -} - - -apacket *get_apacket(void) -{ - apacket *p = malloc(sizeof(apacket)); - if(p == 0) fatal("failed to allocate an apacket"); - memset(p, 0, sizeof(apacket) - MAX_PAYLOAD); - return p; -} - -void put_apacket(apacket *p) -{ - free(p); -} - -void handle_online(void) -{ - D("adb: online\n"); -#if !ADB_HOST - property_set("adb.connected","1"); -#endif -} - -void handle_offline(atransport *t) -{ - D("adb: offline\n"); - //Close the associated usb - run_transport_disconnects(t); -#if !ADB_HOST - property_set("adb.connected",""); -#endif -} - -#if TRACE_PACKETS -#define DUMPMAX 32 -void print_packet(const char *label, apacket *p) -{ - char *tag; - char *x; - unsigned count; - - switch(p->msg.command){ - case A_SYNC: tag = "SYNC"; break; - case A_CNXN: tag = "CNXN" ; break; - case A_OPEN: tag = "OPEN"; break; - case A_OKAY: tag = "OKAY"; break; - case A_CLSE: tag = "CLSE"; break; - case A_WRTE: tag = "WRTE"; break; - default: tag = "????"; break; - } - - fprintf(stderr, "%s: %s %08x %08x %04x \"", - label, tag, p->msg.arg0, p->msg.arg1, p->msg.data_length); - count = p->msg.data_length; - x = (char*) p->data; - if(count > DUMPMAX) { - count = DUMPMAX; - tag = "\n"; - } else { - tag = "\"\n"; - } - while(count-- > 0){ - if((*x >= ' ') && (*x < 127)) { - fputc(*x, stderr); - } else { - fputc('.', stderr); - } - x++; - } - fprintf(stderr, tag); -} -#endif - -static void send_ready(unsigned local, unsigned remote, atransport *t) -{ - D("Calling send_ready \n"); - apacket *p = get_apacket(); - p->msg.command = A_OKAY; - p->msg.arg0 = local; - p->msg.arg1 = remote; - send_packet(p, t); -} - -static void send_close(unsigned local, unsigned remote, atransport *t) -{ - D("Calling send_close \n"); - apacket *p = get_apacket(); - p->msg.command = A_CLSE; - p->msg.arg0 = local; - p->msg.arg1 = remote; - send_packet(p, t); -} - -static void send_connect(atransport *t) -{ - D("Calling send_connect \n"); - apacket *cp = get_apacket(); - cp->msg.command = A_CNXN; - cp->msg.arg0 = A_VERSION; - cp->msg.arg1 = MAX_PAYLOAD; - snprintf((char*) cp->data, sizeof cp->data, "%s::", - HOST ? "host" : adb_device_banner); - cp->msg.data_length = strlen((char*) cp->data) + 1; - send_packet(cp, t); -#if ADB_HOST - /* XXX why sleep here? */ - // allow the device some time to respond to the connect message - adb_sleep_ms(1000); -#endif -} - -static char *connection_state_name(atransport *t) -{ - if (t == NULL) { - return "unknown"; - } - - switch(t->connection_state) { - case CS_BOOTLOADER: - return "bootloader"; - case CS_DEVICE: - return "device"; - case CS_OFFLINE: - return "offline"; - default: - return "unknown"; - } -} - -void parse_banner(char *banner, atransport *t) -{ - char *type, *product, *end; - - D("parse_banner: %s\n", banner); - type = banner; - product = strchr(type, ':'); - if(product) { - *product++ = 0; - } else { - product = ""; - } - - /* remove trailing ':' */ - end = strchr(product, ':'); - if(end) *end = 0; - - /* save product name in device structure */ - if (t->product == NULL) { - t->product = strdup(product); - } else if (strcmp(product, t->product) != 0) { - free(t->product); - t->product = strdup(product); - } - - if(!strcmp(type, "bootloader")){ - D("setting connection_state to CS_BOOTLOADER\n"); - t->connection_state = CS_BOOTLOADER; - update_transports(); - return; - } - - if(!strcmp(type, "device")) { - D("setting connection_state to CS_DEVICE\n"); - t->connection_state = CS_DEVICE; - update_transports(); - return; - } - - if(!strcmp(type, "recovery")) { - D("setting connection_state to CS_RECOVERY\n"); - t->connection_state = CS_RECOVERY; - update_transports(); - return; - } - - t->connection_state = CS_HOST; -} - -void handle_packet(apacket *p, atransport *t) -{ - asocket *s; - - D("handle_packet() %d\n", p->msg.command); - - print_packet("recv", p); - - switch(p->msg.command){ - case A_SYNC: - if(p->msg.arg0){ - send_packet(p, t); - if(HOST) send_connect(t); - } else { - t->connection_state = CS_OFFLINE; - handle_offline(t); - send_packet(p, t); - } - return; - - case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */ - /* XXX verify version, etc */ - if(t->connection_state != CS_OFFLINE) { - t->connection_state = CS_OFFLINE; - handle_offline(t); - } - parse_banner((char*) p->data, t); - handle_online(); - if(!HOST) send_connect(t); - break; - - case A_OPEN: /* OPEN(local-id, 0, "destination") */ - if(t->connection_state != CS_OFFLINE) { - char *name = (char*) p->data; - name[p->msg.data_length > 0 ? p->msg.data_length - 1 : 0] = 0; - s = create_local_service_socket(name); - if(s == 0) { - send_close(0, p->msg.arg0, t); - } else { - s->peer = create_remote_socket(p->msg.arg0, t); - s->peer->peer = s; - send_ready(s->id, s->peer->id, t); - s->ready(s); - } - } - break; - - case A_OKAY: /* READY(local-id, remote-id, "") */ - if(t->connection_state != CS_OFFLINE) { - if((s = find_local_socket(p->msg.arg1))) { - if(s->peer == 0) { - s->peer = create_remote_socket(p->msg.arg0, t); - s->peer->peer = s; - } - s->ready(s); - } - } - break; - - case A_CLSE: /* CLOSE(local-id, remote-id, "") */ - if(t->connection_state != CS_OFFLINE) { - if((s = find_local_socket(p->msg.arg1))) { - s->close(s); - } - } - break; - - case A_WRTE: - if(t->connection_state != CS_OFFLINE) { - if((s = find_local_socket(p->msg.arg1))) { - unsigned rid = p->msg.arg0; - p->len = p->msg.data_length; - - if(s->enqueue(s, p) == 0) { - D("Enqueue the socket\n"); - send_ready(s->id, rid, t); - } - return; - } - } - break; - - default: - printf("handle_packet: what is %08x?!\n", p->msg.command); - } - - put_apacket(p); -} - -alistener listener_list = { - .next = &listener_list, - .prev = &listener_list, -}; - -static void ss_listener_event_func(int _fd, unsigned ev, void *_l) -{ - asocket *s; - - if(ev & FDE_READ) { - struct sockaddr addr; - socklen_t alen; - int fd; - - alen = sizeof(addr); - fd = adb_socket_accept(_fd, &addr, &alen); - if(fd < 0) return; - - adb_socket_setbufsize(fd, CHUNK_SIZE); - - s = create_local_socket(fd); - if(s) { - connect_to_smartsocket(s); - return; - } - - adb_close(fd); - } -} - -static void listener_event_func(int _fd, unsigned ev, void *_l) -{ - alistener *l = _l; - asocket *s; - - if(ev & FDE_READ) { - struct sockaddr addr; - socklen_t alen; - int fd; - - alen = sizeof(addr); - fd = adb_socket_accept(_fd, &addr, &alen); - if(fd < 0) return; - - s = create_local_socket(fd); - if(s) { - s->transport = l->transport; - connect_to_remote(s, l->connect_to); - return; - } - - adb_close(fd); - } -} - -static void free_listener(alistener* l) -{ - if (l->next) { - l->next->prev = l->prev; - l->prev->next = l->next; - l->next = l->prev = l; - } - - // closes the corresponding fd - fdevent_remove(&l->fde); - - if (l->local_name) - free((char*)l->local_name); - - if (l->connect_to) - free((char*)l->connect_to); - - if (l->transport) { - remove_transport_disconnect(l->transport, &l->disconnect); - } - free(l); -} - -static void listener_disconnect(void* _l, atransport* t) -{ - alistener* l = _l; - - free_listener(l); -} - -int local_name_to_fd(const char *name) -{ - int port; - - if(!strncmp("tcp:", name, 4)){ - int ret; - port = atoi(name + 4); - ret = socket_loopback_server(port, SOCK_STREAM); - return ret; - } -#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */ - // It's non-sensical to support the "reserved" space on the adb host side - if(!strncmp(name, "local:", 6)) { - return socket_local_server(name + 6, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - } else if(!strncmp(name, "localabstract:", 14)) { - return socket_local_server(name + 14, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - } else if(!strncmp(name, "localfilesystem:", 16)) { - return socket_local_server(name + 16, - ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); - } - -#endif - printf("unknown local portname '%s'\n", name); - return -1; -} - -static int remove_listener(const char *local_name, const char *connect_to, atransport* transport) -{ - alistener *l; - - for (l = listener_list.next; l != &listener_list; l = l->next) { - if (!strcmp(local_name, l->local_name) && - !strcmp(connect_to, l->connect_to) && - l->transport && l->transport == transport) { - - listener_disconnect(l, transport); - return 0; - } - } - - return -1; -} - -static int install_listener(const char *local_name, const char *connect_to, atransport* transport) -{ - alistener *l; - - //printf("install_listener('%s','%s')\n", local_name, connect_to); - - for(l = listener_list.next; l != &listener_list; l = l->next){ - if(strcmp(local_name, l->local_name) == 0) { - char *cto; - - /* can't repurpose a smartsocket */ - if(l->connect_to[0] == '*') { - return -1; - } - - cto = strdup(connect_to); - if(cto == 0) { - return -1; - } - - //printf("rebinding '%s' to '%s'\n", local_name, connect_to); - free((void*) l->connect_to); - l->connect_to = cto; - if (l->transport != transport) { - remove_transport_disconnect(l->transport, &l->disconnect); - l->transport = transport; - add_transport_disconnect(l->transport, &l->disconnect); - } - return 0; - } - } - - if((l = calloc(1, sizeof(alistener))) == 0) goto nomem; - if((l->local_name = strdup(local_name)) == 0) goto nomem; - if((l->connect_to = strdup(connect_to)) == 0) goto nomem; - - - l->fd = local_name_to_fd(local_name); - if(l->fd < 0) { - free((void*) l->local_name); - free((void*) l->connect_to); - free(l); - printf("cannot bind '%s'\n", local_name); - return -2; - } - - close_on_exec(l->fd); - if(!strcmp(l->connect_to, "*smartsocket*")) { - fdevent_install(&l->fde, l->fd, ss_listener_event_func, l); - } else { - fdevent_install(&l->fde, l->fd, listener_event_func, l); - } - fdevent_set(&l->fde, FDE_READ); - - l->next = &listener_list; - l->prev = listener_list.prev; - l->next->prev = l; - l->prev->next = l; - l->transport = transport; - - if (transport) { - l->disconnect.opaque = l; - l->disconnect.func = listener_disconnect; - add_transport_disconnect(transport, &l->disconnect); - } - return 0; - -nomem: - fatal("cannot allocate listener"); - return 0; -} - -#ifdef HAVE_FORKEXEC -static void sigchld_handler(int n) -{ - int status; - while(waitpid(-1, &status, WNOHANG) > 0) ; -} -#endif - -#ifdef HAVE_WIN32_PROC -static BOOL WINAPI ctrlc_handler(DWORD type) -{ - exit(STATUS_CONTROL_C_EXIT); - return TRUE; -} -#endif - -static void adb_cleanup(void) -{ - usb_cleanup(); -} - -void start_logging(void) -{ -#ifdef HAVE_WIN32_PROC - char temp[ MAX_PATH ]; - FILE* fnul; - FILE* flog; - - GetTempPath( sizeof(temp) - 8, temp ); - strcat( temp, "adb.log" ); - - /* Win32 specific redirections */ - fnul = fopen( "NUL", "rt" ); - if (fnul != NULL) - stdin[0] = fnul[0]; - - flog = fopen( temp, "at" ); - if (flog == NULL) - flog = fnul; - - setvbuf( flog, NULL, _IONBF, 0 ); - - stdout[0] = flog[0]; - stderr[0] = flog[0]; - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#else - int fd; - - fd = unix_open("/dev/null", O_RDONLY); - dup2(fd, 0); - - fd = unix_open("/tmp/adb.log", O_WRONLY | O_CREAT | O_APPEND, 0640); - if(fd < 0) { - fd = unix_open("/dev/null", O_WRONLY); - } - dup2(fd, 1); - dup2(fd, 2); - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); -#endif -} - -#if !ADB_HOST -void start_device_log(void) -{ - int fd; - char path[100]; - - snprintf(path, sizeof path, "/data/adb_%ld.txt", (long)time(NULL)); - fd = unix_open(path, O_WRONLY | O_CREAT | O_APPEND, 0640); - if (fd < 0) - return; - - // redirect stdout and stderr to the log file - dup2(fd, 1); - dup2(fd, 2); - fprintf(stderr,"--- adb starting (pid %d) ---\n", getpid()); - - fd = unix_open("/dev/null", O_RDONLY); - dup2(fd, 0); - - // log everything - adb_trace_mask = ~0; - // except TRACE_RWX is a bit too verbose - adb_trace_mask &= ~TRACE_RWX; -} -#endif - -#if ADB_HOST -int launch_server() -{ -#ifdef HAVE_WIN32_PROC - /* we need to start the server in the background */ - /* we create a PIPE that will be used to wait for the server's "OK" */ - /* message since the pipe handles must be inheritable, we use a */ - /* security attribute */ - HANDLE pipe_read, pipe_write; - SECURITY_ATTRIBUTES sa; - STARTUPINFO startup; - PROCESS_INFORMATION pinfo; - char program_path[ MAX_PATH ]; - int ret; - - sa.nLength = sizeof(sa); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - /* create pipe, and ensure its read handle isn't inheritable */ - ret = CreatePipe( &pipe_read, &pipe_write, &sa, 0 ); - if (!ret) { - fprintf(stderr, "CreatePipe() failure, error %ld\n", GetLastError() ); - return -1; - } - - SetHandleInformation( pipe_read, HANDLE_FLAG_INHERIT, 0 ); - - ZeroMemory( &startup, sizeof(startup) ); - startup.cb = sizeof(startup); - startup.hStdInput = GetStdHandle( STD_INPUT_HANDLE ); - startup.hStdOutput = pipe_write; - startup.hStdError = GetStdHandle( STD_ERROR_HANDLE ); - startup.dwFlags = STARTF_USESTDHANDLES; - - ZeroMemory( &pinfo, sizeof(pinfo) ); - - /* get path of current program */ - GetModuleFileName( NULL, program_path, sizeof(program_path) ); - - ret = CreateProcess( - program_path, /* program path */ - "adb fork-server server", - /* the fork-server argument will set the - debug = 2 in the child */ - NULL, /* process handle is not inheritable */ - NULL, /* thread handle is not inheritable */ - TRUE, /* yes, inherit some handles */ - DETACHED_PROCESS, /* the new process doesn't have a console */ - NULL, /* use parent's environment block */ - NULL, /* use parent's starting directory */ - &startup, /* startup info, i.e. std handles */ - &pinfo ); - - CloseHandle( pipe_write ); - - if (!ret) { - fprintf(stderr, "CreateProcess failure, error %ld\n", GetLastError() ); - CloseHandle( pipe_read ); - return -1; - } - - CloseHandle( pinfo.hProcess ); - CloseHandle( pinfo.hThread ); - - /* wait for the "OK\n" message */ - { - char temp[3]; - DWORD count; - - ret = ReadFile( pipe_read, temp, 3, &count, NULL ); - CloseHandle( pipe_read ); - if ( !ret ) { - fprintf(stderr, "could not read ok from ADB Server, error = %ld\n", GetLastError() ); - return -1; - } - if (count != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "ADB server didn't ACK\n" ); - return -1; - } - } -#elif defined(HAVE_FORKEXEC) - char path[PATH_MAX]; - int fd[2]; - - // set up a pipe so the child can tell us when it is ready. - // fd[0] will be parent's end, and fd[1] will get mapped to stderr in the child. - if (pipe(fd)) { - fprintf(stderr, "pipe failed in launch_server, errno: %d\n", errno); - return -1; - } - get_my_path(path); - pid_t pid = fork(); - if(pid < 0) return -1; - - if (pid == 0) { - // child side of the fork - - // redirect stderr to the pipe - // we use stderr instead of stdout due to stdout's buffering behavior. - adb_close(fd[0]); - dup2(fd[1], STDERR_FILENO); - adb_close(fd[1]); - - // child process - int result = execl(path, "adb", "fork-server", "server", NULL); - // this should not return - fprintf(stderr, "OOPS! execl returned %d, errno: %d\n", result, errno); - } else { - // parent side of the fork - - char temp[3]; - - temp[0] = 'A'; temp[1] = 'B'; temp[2] = 'C'; - // wait for the "OK\n" message - adb_close(fd[1]); - int ret = adb_read(fd[0], temp, 3); - adb_close(fd[0]); - if (ret < 0) { - fprintf(stderr, "could not read ok from ADB Server, errno = %d\n", errno); - return -1; - } - if (ret != 3 || temp[0] != 'O' || temp[1] != 'K' || temp[2] != '\n') { - fprintf(stderr, "ADB server didn't ACK\n" ); - return -1; - } - - setsid(); - } -#else -#error "cannot implement background server start on this platform" -#endif - return 0; -} -#endif - -int adb_main(int is_daemon) -{ -#if !ADB_HOST - int secure = 0; - char value[PROPERTY_VALUE_MAX]; - - // prevent the OOM killer from killing us - char text[64]; - snprintf(text, sizeof text, "/proc/%d/oom_adj", (int)getpid()); - int fd = adb_open(text, O_WRONLY); - if (fd >= 0) { - // -17 should make us immune to OOM - snprintf(text, sizeof text, "%d", -17); - adb_write(fd, text, strlen(text)); - adb_close(fd); - } else { - D("adb: unable to open %s\n", text); - } -#endif - - atexit(adb_cleanup); -#ifdef HAVE_WIN32_PROC - SetConsoleCtrlHandler( ctrlc_handler, TRUE ); -#elif defined(HAVE_FORKEXEC) - signal(SIGCHLD, sigchld_handler); - signal(SIGPIPE, SIG_IGN); -#endif - - init_transport_registration(); - - -#if ADB_HOST - HOST = 1; - usb_init(); - local_init(); - - if(install_listener("tcp:5037", "*smartsocket*", NULL)) { - exit(1); - } -#else - /* run adbd in secure mode if ro.secure is set and - ** we are not in the emulator - */ - property_get("ro.kernel.qemu", value, ""); - if (strcmp(value, "1") != 0) { - property_get("ro.secure", value, ""); - if (strcmp(value, "1") == 0) - secure = 1; - } - - /* don't listen on port 5037 if we are running in secure mode */ - /* don't run as root if we are running in secure mode */ - if (secure) { - /* add extra groups: - ** AID_ADB to access the USB driver - ** AID_LOG to read system logs (adb logcat) - ** AID_INPUT to diagnose input issues (getevent) - ** AID_INET to diagnose network issues (netcfg, ping) - ** AID_GRAPHICS to access the frame buffer - */ - gid_t groups[] = { AID_ADB, AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS }; - setgroups(sizeof(groups)/sizeof(groups[0]), groups); - - /* then switch user and group to "shell" */ - setgid(AID_SHELL); - setuid(AID_SHELL); - - D("Local port 5037 disabled\n"); - } else { - if(install_listener("tcp:5037", "*smartsocket*", NULL)) { - exit(1); - } - } - - /* for the device, start the usb transport if the - ** android usb device exists, otherwise start the - ** network transport. - */ - if(access("/dev/android_adb", F_OK) == 0 || - access("/dev/android", F_OK) == 0) { - usb_init(); - } else { - local_init(); - } - init_jdwp(); -#endif - - if (is_daemon) - { - // inform our parent that we are up and running. -#ifdef HAVE_WIN32_PROC - DWORD count; - WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), "OK\n", 3, &count, NULL ); -#elif defined(HAVE_FORKEXEC) - fprintf(stderr, "OK\n"); -#endif - start_logging(); - } - - fdevent_loop(); - - usb_cleanup(); - - return 0; -} - -int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s) -{ - atransport *transport = NULL; - char buf[4096]; - - if(!strcmp(service, "kill")) { - fprintf(stderr,"adb server killed by remote request\n"); - fflush(stdout); - adb_write(reply_fd, "OKAY", 4); - usb_cleanup(); - exit(0); - } - -#if ADB_HOST - // "transport:" is used for switching transport with a specified serial number - // "transport-usb:" is used for switching transport to the only USB transport - // "transport-local:" is used for switching transport to the only local transport - // "transport-any:" is used for switching transport to the only transport - if (!strncmp(service, "transport", strlen("transport"))) { - char* error_string = "unknown failure"; - transport_type type = kTransportAny; - - if (!strncmp(service, "transport-usb", strlen("transport-usb"))) { - type = kTransportUsb; - } else if (!strncmp(service, "transport-local", strlen("transport-local"))) { - type = kTransportLocal; - } else if (!strncmp(service, "transport-any", strlen("transport-any"))) { - type = kTransportAny; - } else if (!strncmp(service, "transport:", strlen("transport:"))) { - service += strlen("transport:"); - serial = strdup(service); - } - - transport = acquire_one_transport(CS_ANY, type, serial, &error_string); - - if (transport) { - s->transport = transport; - adb_write(reply_fd, "OKAY", 4); - } else { - sendfailmsg(reply_fd, error_string); - } - return 1; - } - - // return a list of all connected devices - if (!strcmp(service, "devices")) { - char buffer[4096]; - memset(buf, 0, sizeof(buf)); - memset(buffer, 0, sizeof(buffer)); - D("Getting device list \n"); - list_transports(buffer, sizeof(buffer)); - snprintf(buf, sizeof(buf), "OKAY%04x%s",(unsigned)strlen(buffer),buffer); - D("Wrote device list \n"); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - // returns our value for ADB_SERVER_VERSION - if (!strcmp(service, "version")) { - char version[12]; - snprintf(version, sizeof version, "%04x", ADB_SERVER_VERSION); - snprintf(buf, sizeof buf, "OKAY%04x%s", (unsigned)strlen(version), version); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - - if(!strncmp(service,"get-serialno",strlen("get-serialno"))) { - char *out = "unknown"; - transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - if (transport && transport->serial) { - out = transport->serial; - } - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(out),out); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - // indicates a new emulator instance has started - if (!strncmp(service,"emulator:",9)) { - int port = atoi(service+9); - local_connect(port); - /* we don't even need to send a reply */ - return 0; - } -#endif // ADB_HOST - - if(!strncmp(service,"forward:",8) || !strncmp(service,"killforward:",12)) { - char *local, *remote, *err; - int r; - atransport *transport; - - int createForward = strncmp(service,"kill",4); - - local = service + (createForward ? 8 : 12); - remote = strchr(local,';'); - if(remote == 0) { - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - - *remote++ = 0; - if((local[0] == 0) || (remote[0] == 0) || (remote[0] == '*')){ - sendfailmsg(reply_fd, "malformed forward spec"); - return 0; - } - - transport = acquire_one_transport(CS_ANY, ttype, serial, &err); - if (!transport) { - sendfailmsg(reply_fd, err); - return 0; - } - - if (createForward) { - r = install_listener(local, remote, transport); - } else { - r = remove_listener(local, remote, transport); - } - if(r == 0) { - /* 1st OKAY is connect, 2nd OKAY is status */ - writex(reply_fd, "OKAYOKAY", 8); - return 0; - } - - if (createForward) { - sendfailmsg(reply_fd, (r == -1) ? "cannot rebind smartsocket" : "cannot bind socket"); - } else { - sendfailmsg(reply_fd, "cannot remove listener"); - } - return 0; - } - - if(!strncmp(service,"get-state",strlen("get-state"))) { - transport = acquire_one_transport(CS_ANY, ttype, serial, NULL); - char *state = connection_state_name(transport); - snprintf(buf, sizeof buf, "OKAY%04x%s",(unsigned)strlen(state),state); - writex(reply_fd, buf, strlen(buf)); - return 0; - } - return -1; -} - -#if !ADB_HOST -int recovery_mode = 0; -#endif - -int main(int argc, char **argv) -{ - adb_trace_init(); -#if ADB_HOST - adb_sysdeps_init(); - return adb_commandline(argc - 1, argv + 1); -#else - if((argc > 1) && (!strcmp(argv[1],"recovery"))) { - adb_device_banner = "recovery"; - recovery_mode = 1; - } -#if ADB_DEVICE_LOG - start_device_log(); -#endif - return adb_main(0); -#endif -} - diff --git a/adb/adb.h b/adb/adb.h deleted file mode 100644 index a17c8ddc5499c419bb2e86a38221e52750915bbb..0000000000000000000000000000000000000000 --- a/adb/adb.h +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __ADB_H -#define __ADB_H - -#include <limits.h> - -#define MAX_PAYLOAD 4096 - -#define A_SYNC 0x434e5953 -#define A_CNXN 0x4e584e43 -#define A_OPEN 0x4e45504f -#define A_OKAY 0x59414b4f -#define A_CLSE 0x45534c43 -#define A_WRTE 0x45545257 - -#define A_VERSION 0x01000000 // ADB protocol version - -#define ADB_VERSION_MAJOR 1 // Used for help/version information -#define ADB_VERSION_MINOR 0 // Used for help/version information - -#define ADB_SERVER_VERSION 20 // Increment this when we want to force users to start a new adb server - -typedef struct amessage amessage; -typedef struct apacket apacket; -typedef struct asocket asocket; -typedef struct alistener alistener; -typedef struct aservice aservice; -typedef struct atransport atransport; -typedef struct adisconnect adisconnect; -typedef struct usb_handle usb_handle; - -struct amessage { - unsigned command; /* command identifier constant */ - unsigned arg0; /* first argument */ - unsigned arg1; /* second argument */ - unsigned data_length; /* length of payload (0 is allowed) */ - unsigned data_check; /* checksum of data payload */ - unsigned magic; /* command ^ 0xffffffff */ -}; - -struct apacket -{ - apacket *next; - - unsigned len; - unsigned char *ptr; - - amessage msg; - unsigned char data[MAX_PAYLOAD]; -}; - -/* An asocket represents one half of a connection between a local and -** remote entity. A local asocket is bound to a file descriptor. A -** remote asocket is bound to the protocol engine. -*/ -struct asocket { - /* chain pointers for the local/remote list of - ** asockets that this asocket lives in - */ - asocket *next; - asocket *prev; - - /* the unique identifier for this asocket - */ - unsigned id; - - /* flag: set when the socket's peer has closed - ** but packets are still queued for delivery - */ - int closing; - - /* the asocket we are connected to - */ - - asocket *peer; - - /* For local asockets, the fde is used to bind - ** us to our fd event system. For remote asockets - ** these fields are not used. - */ - fdevent fde; - int fd; - - /* queue of apackets waiting to be written - */ - apacket *pkt_first; - apacket *pkt_last; - - /* enqueue is called by our peer when it has data - ** for us. It should return 0 if we can accept more - ** data or 1 if not. If we return 1, we must call - ** peer->ready() when we once again are ready to - ** receive data. - */ - int (*enqueue)(asocket *s, apacket *pkt); - - /* ready is called by the peer when it is ready for - ** us to send data via enqueue again - */ - void (*ready)(asocket *s); - - /* close is called by the peer when it has gone away. - ** we are not allowed to make any further calls on the - ** peer once our close method is called. - */ - void (*close)(asocket *s); - - /* socket-type-specific extradata */ - void *extra; - - /* A socket is bound to atransport */ - atransport *transport; -}; - - -/* the adisconnect structure is used to record a callback that -** will be called whenever a transport is disconnected (e.g. by the user) -** this should be used to cleanup objects that depend on the -** transport (e.g. remote sockets, listeners, etc...) -*/ -struct adisconnect -{ - void (*func)(void* opaque, atransport* t); - void* opaque; - adisconnect* next; - adisconnect* prev; -}; - - -/* a transport object models the connection to a remote device or emulator -** there is one transport per connected device/emulator. a "local transport" -** connects through TCP (for the emulator), while a "usb transport" through -** USB (for real devices) -** -** note that kTransportHost doesn't really correspond to a real transport -** object, it's a special value used to indicate that a client wants to -** connect to a service implemented within the ADB server itself. -*/ -typedef enum transport_type { - kTransportUsb, - kTransportLocal, - kTransportAny, - kTransportHost, -} transport_type; - -struct atransport -{ - atransport *next; - atransport *prev; - - int (*read_from_remote)(apacket *p, atransport *t); - int (*write_to_remote)(apacket *p, atransport *t); - void (*close)(atransport *t); - void (*kick)(atransport *t); - - int fd; - int transport_socket; - fdevent transport_fde; - int ref_count; - unsigned sync_token; - int connection_state; - transport_type type; - - /* usb handle or socket fd as needed */ - usb_handle *usb; - int sfd; - - /* used to identify transports for clients */ - char *serial; - char *product; - - /* a list of adisconnect callbacks called when the transport is kicked */ - int kicked; - adisconnect disconnects; -}; - - -/* A listener is an entity which binds to a local port -** and, upon receiving a connection on that port, creates -** an asocket to connect the new local connection to a -** specific remote service. -** -** TODO: some listeners read from the new connection to -** determine what exact service to connect to on the far -** side. -*/ -struct alistener -{ - alistener *next; - alistener *prev; - - fdevent fde; - int fd; - - const char *local_name; - const char *connect_to; - atransport *transport; - adisconnect disconnect; -}; - - -void print_packet(const char *label, apacket *p); - -asocket *find_local_socket(unsigned id); -void install_local_socket(asocket *s); -void remove_socket(asocket *s); -void close_all_sockets(atransport *t); - -#define LOCAL_CLIENT_PREFIX "emulator-" - -asocket *create_local_socket(int fd); -asocket *create_local_service_socket(const char *destination); - -asocket *create_remote_socket(unsigned id, atransport *t); -void connect_to_remote(asocket *s, const char *destination); -void connect_to_smartsocket(asocket *s); - -void fatal(const char *fmt, ...); -void fatal_errno(const char *fmt, ...); - -void handle_packet(apacket *p, atransport *t); -void send_packet(apacket *p, atransport *t); - -void get_my_path(char s[PATH_MAX]); -int launch_server(); -int adb_main(int is_daemon); - - -/* transports are ref-counted -** get_device_transport does an acquire on your behalf before returning -*/ -void init_transport_registration(void); -int list_transports(char *buf, size_t bufsize); -void update_transports(void); - -asocket* create_device_tracker(void); - -/* Obtain a transport from the available transports. -** If state is != CS_ANY, only transports in that state are considered. -** If serial is non-NULL then only the device with that serial will be chosen. -** If no suitable transport is found, error is set. -*/ -atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char **error_out); -void add_transport_disconnect( atransport* t, adisconnect* dis ); -void remove_transport_disconnect( atransport* t, adisconnect* dis ); -void run_transport_disconnects( atransport* t ); -void kick_transport( atransport* t ); - -/* initialize a transport object's func pointers and state */ -int init_socket_transport(atransport *t, int s, int port); -void init_usb_transport(atransport *t, usb_handle *usb); - -/* for MacOS X cleanup */ -void close_usb_devices(); - -/* cause new transports to be init'd and added to the list */ -void register_socket_transport(int s, const char *serial, int port); -void register_usb_transport(usb_handle *h, const char *serial); - -int service_to_fd(const char *name); -#if ADB_HOST -asocket *host_service_to_socket(const char* name, const char *serial); -#endif - -#if !ADB_HOST -int init_jdwp(void); -asocket* create_jdwp_service_socket(); -asocket* create_jdwp_tracker_service_socket(); -int create_jdwp_connection_fd(int jdwp_pid); -#endif - -#if !ADB_HOST -void framebuffer_service(int fd, void *cookie); -void log_service(int fd, void *cookie); -void remount_service(int fd, void *cookie); -char * get_log_file_path(const char * log_name); -#endif - -/* packet allocator */ -apacket *get_apacket(void); -void put_apacket(apacket *p); - -int check_header(apacket *p); -int check_data(apacket *p); - -/* convenience wrappers around read/write that will retry on -** EINTR and/or short read/write. Returns 0 on success, -1 -** on error or EOF. -*/ -int readx(int fd, void *ptr, size_t len); -int writex(int fd, const void *ptr, size_t len); - -/* define ADB_TRACE to 1 to enable tracing support, or 0 to disable it */ - -#define ADB_TRACE 1 - -/* IMPORTANT: if you change the following list, don't - * forget to update the corresponding 'tags' table in - * the adb_trace_init() function implemented in adb.c - */ -typedef enum { - TRACE_ADB = 0, - TRACE_SOCKETS, - TRACE_PACKETS, - TRACE_TRANSPORT, - TRACE_RWX, - TRACE_USB, - TRACE_SYNC, - TRACE_SYSDEPS, - TRACE_JDWP, -} AdbTrace; - -#if ADB_TRACE - - int adb_trace_mask; - - void adb_trace_init(void); - -# define ADB_TRACING ((adb_trace_mask & (1 << TRACE_TAG)) != 0) - - /* you must define TRACE_TAG before using this macro */ - #define D(...) \ - do { \ - if (ADB_TRACING) \ - fprintf(stderr, __VA_ARGS__ ); \ - } while (0) -#else -# define D(...) ((void)0) -# define ADB_TRACING 0 -#endif - - -/* set this to log to /data/adb/adb_<time>.txt on the device. - * has no effect if the /data/adb/ directory does not exist. - */ -#define ADB_DEVICE_LOG 0 - -#if !TRACE_PACKETS -#define print_packet(tag,p) do {} while (0) -#endif - -#define ADB_PORT 5037 -#define ADB_LOCAL_TRANSPORT_PORT 5555 - -// Google's USB Vendor ID -#define VENDOR_ID_GOOGLE 0x18d1 -// HTC's USB Vendor ID -#define VENDOR_ID_HTC 0x0bb4 - -// products for VENDOR_ID_GOOGLE -#define PRODUCT_ID_SOONER 0xd00d // Sooner bootloader -#define PRODUCT_ID_SOONER_COMP 0xdeed // Sooner composite device - -// products for VENDOR_ID_HTC -#define PRODUCT_ID_DREAM 0x0c01 // Dream bootloader -#define PRODUCT_ID_DREAM_COMP 0x0c02 // Dream composite device - -void local_init(); -int local_connect(int port); - -/* usb host/client interface */ -void usb_init(); -void usb_cleanup(); -int usb_write(usb_handle *h, const void *data, int len); -int usb_read(usb_handle *h, void *data, int len); -int usb_close(usb_handle *h); -void usb_kick(usb_handle *h); - -/* used for USB device detection */ -int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol); - -unsigned host_to_le32(unsigned n); -int adb_commandline(int argc, char **argv); - -int connection_state(atransport *t); - -#define CS_ANY -1 -#define CS_OFFLINE 0 -#define CS_BOOTLOADER 1 -#define CS_DEVICE 2 -#define CS_HOST 3 -#define CS_RECOVERY 4 -#define CS_ERROR 5 - -extern int HOST; - -#define CHUNK_SIZE (64*1024) - -int sendfailmsg(int fd, const char *reason); -int handle_host_request(char *service, transport_type ttype, char* serial, int reply_fd, asocket *s); - -#endif diff --git a/adb/adb_client.c b/adb/adb_client.c deleted file mode 100644 index 58687448060f1423520d8dfa287cba0d21806f8b..0000000000000000000000000000000000000000 --- a/adb/adb_client.c +++ /dev/null @@ -1,318 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <stdarg.h> -#include <zipfile/zipfile.h> -#include <sys/types.h> -#include <sys/stat.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_ADB -#include "adb_client.h" - -static transport_type __adb_transport = kTransportAny; -static const char* __adb_serial = NULL; - -void adb_set_transport(transport_type type, const char* serial) -{ - __adb_transport = type; - __adb_serial = serial; -} - -int adb_get_emulator_console_port(void) -{ - const char* serial = __adb_serial; - int port; - - if (serial == NULL) { - /* if no specific device was specified, we need to look at */ - /* the list of connected devices, and extract an emulator */ - /* name from it. two emulators is an error */ - char* tmp = adb_query("host:devices"); - char* p = tmp; - if(!tmp) { - printf("no emulator connected\n"); - return -1; - } - while (*p) { - char* q = strchr(p, '\n'); - if (q != NULL) - *q++ = 0; - else - q = p + strlen(p); - - if (!memcmp(p, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1)) { - if (serial != NULL) { /* more than one emulator listed */ - free(tmp); - return -2; - } - serial = p; - } - - p = q; - } - free(tmp); - - if (serial == NULL) - return -1; /* no emulator found */ - } - else { - if (memcmp(serial, LOCAL_CLIENT_PREFIX, sizeof(LOCAL_CLIENT_PREFIX)-1) != 0) - return -1; /* not an emulator */ - } - - serial += sizeof(LOCAL_CLIENT_PREFIX)-1; - port = strtol(serial, NULL, 10); - return port; -} - -static char __adb_error[256] = { 0 }; - -const char *adb_error(void) -{ - return __adb_error; -} - -static int switch_socket_transport(int fd) -{ - char service[64]; - char tmp[5]; - int len; - - if (__adb_serial) - snprintf(service, sizeof service, "host:transport:%s", __adb_serial); - else { - char* transport_type = "???"; - - switch (__adb_transport) { - case kTransportUsb: - transport_type = "transport-usb"; - break; - case kTransportLocal: - transport_type = "transport-local"; - break; - case kTransportAny: - transport_type = "transport-any"; - break; - case kTransportHost: - // no switch necessary - return 0; - break; - } - - snprintf(service, sizeof service, "host:%s", transport_type); - } - len = strlen(service); - snprintf(tmp, sizeof tmp, "%04x", len); - - if(writex(fd, tmp, 4) || writex(fd, service, len)) { - strcpy(__adb_error, "write failure during connection"); - adb_close(fd); - return -1; - } - D("Switch transport in progress\n"); - - if(adb_status(fd)) { - adb_close(fd); - D("Switch transport failed\n"); - return -1; - } - D("Switch transport success\n"); - return 0; -} - -int adb_status(int fd) -{ - unsigned char buf[5]; - unsigned len; - - if(readx(fd, buf, 4)) { - strcpy(__adb_error, "protocol fault (no status)"); - return -1; - } - - if(!memcmp(buf, "OKAY", 4)) { - return 0; - } - - if(memcmp(buf, "FAIL", 4)) { - sprintf(__adb_error, - "protocol fault (status %02x %02x %02x %02x?!)", - buf[0], buf[1], buf[2], buf[3]); - return -1; - } - - if(readx(fd, buf, 4)) { - strcpy(__adb_error, "protocol fault (status len)"); - return -1; - } - buf[4] = 0; - len = strtoul((char*)buf, 0, 16); - if(len > 255) len = 255; - if(readx(fd, __adb_error, len)) { - strcpy(__adb_error, "protocol fault (status read)"); - return -1; - } - __adb_error[len] = 0; - return -1; -} - -int _adb_connect(const char *service) -{ - char tmp[5]; - int len; - int fd; - - D("_adb_connect: %s\n", service); - len = strlen(service); - if((len < 1) || (len > 1024)) { - strcpy(__adb_error, "service name too long"); - return -1; - } - snprintf(tmp, sizeof tmp, "%04x", len); - - fd = socket_loopback_client(ADB_PORT, SOCK_STREAM); - if(fd < 0) { - strcpy(__adb_error, "cannot connect to daemon"); - return -2; - } - - if (memcmp(service,"host",4) != 0 && switch_socket_transport(fd)) { - return -1; - } - - if(writex(fd, tmp, 4) || writex(fd, service, len)) { - strcpy(__adb_error, "write failure during connection"); - adb_close(fd); - return -1; - } - - if(adb_status(fd)) { - adb_close(fd); - return -1; - } - - return fd; -} - -int adb_connect(const char *service) -{ - // first query the adb server's version - int fd = _adb_connect("host:version"); - - if(fd == -2) { - fprintf(stdout,"* daemon not running. starting it now *\n"); - start_server: - if(launch_server(0)) { - fprintf(stderr,"* failed to start daemon *\n"); - return -1; - } else { - fprintf(stdout,"* daemon started successfully *\n"); - } - /* give the server some time to start properly and detect devices */ - adb_sleep_ms(2000); - // fall through to _adb_connect - } else { - // if server was running, check its version to make sure it is not out of date - char buf[100]; - int n; - int version = ADB_SERVER_VERSION - 1; - - // if we have a file descriptor, then parse version result - if(fd >= 0) { - if(readx(fd, buf, 4)) goto error; - - buf[4] = 0; - n = strtoul(buf, 0, 16); - if(n > (int)sizeof(buf)) goto error; - if(readx(fd, buf, n)) goto error; - adb_close(fd); - - if (sscanf(buf, "%04x", &version) != 1) goto error; - } else { - // if fd is -1, then check for "unknown host service", - // which would indicate a version of adb that does not support the version command - if (strcmp(__adb_error, "unknown host service") != 0) - return fd; - } - - if(version != ADB_SERVER_VERSION) { - printf("adb server is out of date. killing...\n"); - fd = _adb_connect("host:kill"); - adb_close(fd); - - /* XXX can we better detect its death? */ - adb_sleep_ms(2000); - goto start_server; - } - } - - // if the command is start-server, we are done. - if (!strcmp(service, "host:start-server")) - return 0; - - fd = _adb_connect(service); - if(fd == -2) { - fprintf(stderr,"** daemon still not running"); - } - - return fd; -error: - adb_close(fd); - return -1; -} - - -int adb_command(const char *service) -{ - int fd = adb_connect(service); - if(fd < 0) { - return -1; - } - - if(adb_status(fd)) { - adb_close(fd); - return -1; - } - - return 0; -} - -char *adb_query(const char *service) -{ - char buf[5]; - unsigned n; - char *tmp; - - D("adb_query: %s\n", service); - int fd = adb_connect(service); - if(fd < 0) { - fprintf(stderr,"error: %s\n", __adb_error); - return 0; - } - - if(readx(fd, buf, 4)) goto oops; - - buf[4] = 0; - n = strtoul(buf, 0, 16); - if(n > 1024) goto oops; - - tmp = malloc(n + 1); - if(tmp == 0) goto oops; - - if(readx(fd, tmp, n) == 0) { - tmp[n] = 0; - adb_close(fd); - return tmp; - } - free(tmp); - -oops: - adb_close(fd); - return 0; -} - - diff --git a/adb/adb_client.h b/adb/adb_client.h deleted file mode 100644 index 80615790c46f16aa1b451e47878e38bbed19aaf6..0000000000000000000000000000000000000000 --- a/adb/adb_client.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _ADB_CLIENT_H_ -#define _ADB_CLIENT_H_ - -#include "adb.h" - -/* connect to adb, connect to the named service, and return -** a valid fd for interacting with that service upon success -** or a negative number on failure -*/ -int adb_connect(const char *service); -int _adb_connect(const char *service); - -/* connect to adb, connect to the named service, return 0 if -** the connection succeeded AND the service returned OKAY -*/ -int adb_command(const char *service); - -/* connect to adb, connect to the named service, return -** a malloc'd string of its response upon success or NULL -** on failure. -*/ -char *adb_query(const char *service); - -/* Set the preferred transport to connect to. -*/ -void adb_set_transport(transport_type type, const char* serial); - -/* Return the console port of the currently connected emulator (if any) - * of -1 if there is no emulator, and -2 if there is more than one. - * assumes adb_set_transport() was alled previously... - */ -int adb_get_emulator_console_port(void); - -/* send commands to the current emulator instance. will fail if there - * is zero, or more than one emulator connected (or if you use -s <serial> - * with a <serial> that does not designate an emulator) - */ -int adb_send_emulator_command(int argc, char** argv); - -/* return verbose error string from last operation */ -const char *adb_error(void); - -/* read a standard adb status response (OKAY|FAIL) and -** return 0 in the event of OKAY, -1 in the event of FAIL -** or protocol error -*/ -int adb_status(int fd); - -#endif diff --git a/adb/commandline.c b/adb/commandline.c deleted file mode 100644 index be596ce55c0a53902ee7a17b6d711ec36bd88a37..0000000000000000000000000000000000000000 --- a/adb/commandline.c +++ /dev/null @@ -1,1249 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <limits.h> -#include <stdarg.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> -#include <assert.h> - -#include "sysdeps.h" - -#ifdef HAVE_TERMIO_H -#include <termios.h> -#endif - -#define TRACE_TAG TRACE_ADB -#include "adb.h" -#include "adb_client.h" -#include "file_sync_service.h" - -#ifdef SH_HISTORY -#include "shlist.h" -#include "history.h" -#endif - -enum { - IGNORE_DATA, - WIPE_DATA, - FLASH_DATA -}; - -static int do_cmd(transport_type ttype, char* serial, char *cmd, ...); - -void get_my_path(char s[PATH_MAX]); -int find_sync_dirs(const char *srcarg, - char **android_srcdir_out, char **data_srcdir_out); -int install_app(transport_type transport, char* serial, int argc, char** argv); -int uninstall_app(transport_type transport, char* serial, int argc, char** argv); - -static const char *gProductOutPath = NULL; - -static char *product_file(const char *extra) -{ - int n; - char *x; - - if (gProductOutPath == NULL) { - fprintf(stderr, "adb: Product directory not specified; " - "use -p or define ANDROID_PRODUCT_OUT\n"); - exit(1); - } - - n = strlen(gProductOutPath) + strlen(extra) + 2; - x = malloc(n); - if (x == 0) { - fprintf(stderr, "adb: Out of memory (product_file())\n"); - exit(1); - } - - snprintf(x, (size_t)n, "%s" OS_PATH_SEPARATOR_STR "%s", gProductOutPath, extra); - return x; -} - -void version(FILE * out) { - fprintf(out, "Android Debug Bridge version %d.%d.%d\n", - ADB_VERSION_MAJOR, ADB_VERSION_MINOR, ADB_SERVER_VERSION); -} - -void help() -{ - version(stderr); - - fprintf(stderr, - "\n" - " -d - directs command to the only connected USB device\n" - " returns an error if more than one USB device is present.\n" - " -e - directs command to the only running emulator.\n" - " returns an error if more than one emulator is running.\n" - " -s <serial number> - directs command to the USB device or emulator with\n" - " the given serial number\n" - " -p <product name or path> - simple product name like 'sooner', or\n" - " a relative/absolute path to a product\n" - " out directory like 'out/target/product/sooner'.\n" - " If -p is not specified, the ANDROID_PRODUCT_OUT\n" - " environment variable is used, which must\n" - " be an absolute path.\n" - " devices - list all connected devices\n" - "\n" - "device commands:\n" - " adb push <local> <remote> - copy file/dir to device\n" - " adb pull <remote> <local> - copy file/dir from device\n" - " adb sync [ <directory> ] - copy host->device only if changed\n" - " (see 'adb help all')\n" - " adb shell - run remote shell interactively\n" - " adb shell <command> - run remote shell command\n" - " adb emu <command> - run emulator console command\n" - " adb logcat [ <filter-spec> ] - View device log\n" - " adb forward <local> <remote> - forward socket connections\n" - " forward specs are one of: \n" - " tcp:<port>\n" - " localabstract:<unix domain socket name>\n" - " localreserved:<unix domain socket name>\n" - " localfilesystem:<unix domain socket name>\n" - " dev:<character device name>\n" - " jdwp:<process pid> (remote only)\n" - " adb jdwp - list PIDs of processes hosting a JDWP transport\n" - " adb install [-l] [-r] <file> - push this package file to the device and install it\n" - " ('-l' means forward-lock the app)\n" - " ('-r' means reinstall the app, keeping its data)\n" - " adb uninstall [-k] <package> - remove this app package from the device\n" - " ('-k' means keep the data and cache directories)\n" - " adb bugreport - return all information from the device\n" - " that should be included in a bug report.\n" - "\n" - " adb help - show this help message\n" - " adb version - show version num\n" - "\n" - "DATAOPTS:\n" - " (no option) - don't touch the data partition\n" - " -w - wipe the data partition\n" - " -d - flash the data partition\n" - "\n" - "scripting:\n" - " adb wait-for-device - block until device is online\n" - " adb start-server - ensure that there is a server running\n" - " adb kill-server - kill the server if it is running\n" - " adb get-state - prints: offline | bootloader | device\n" - " adb get-serialno - prints: <serial-number>\n" - " adb status-window - continuously print device status for a specified device\n" - " adb remount - remounts the /system partition on the device read-write\n" - "\n" - "networking:\n" - " adb ppp <tty> [parameters] - Run PPP over USB.\n" - " Note: you should not automatically start a PDP connection.\n" - " <tty> refers to the tty for PPP stream. Eg. dev:/dev/omap_csmi_tty1\n" - " [parameters] - Eg. defaultroute debug dump local notty usepeerdns\n" - "\n" - "adb sync notes: adb sync [ <directory> ]\n" - " <localdir> can be interpreted in several ways:\n" - "\n" - " - If <directory> is not specified, both /system and /data partitions will be updated.\n" - "\n" - " - If it is \"system\" or \"data\", only the corresponding partition\n" - " is updated.\n" - ); -} - -int usage() -{ - help(); - return 1; -} - -#ifdef HAVE_TERMIO_H -static struct termios tio_save; - -static void stdin_raw_init(int fd) -{ - struct termios tio; - - if(tcgetattr(fd, &tio)) return; - if(tcgetattr(fd, &tio_save)) return; - - tio.c_lflag = 0; /* disable CANON, ECHO*, etc */ - - /* no timeout but request at least one character per read */ - tio.c_cc[VTIME] = 0; - tio.c_cc[VMIN] = 1; - - tcsetattr(fd, TCSANOW, &tio); - tcflush(fd, TCIFLUSH); -} - -static void stdin_raw_restore(int fd) -{ - tcsetattr(fd, TCSANOW, &tio_save); - tcflush(fd, TCIFLUSH); -} -#endif - -static void read_and_dump(int fd) -{ - char buf[4096]; - int len; - - while(fd >= 0) { - len = adb_read(fd, buf, 4096); - if(len == 0) { - break; - } - - if(len < 0) { - if(errno == EINTR) continue; - break; - } - /* we want to output to stdout, so no adb_write here !! */ - unix_write(1, buf, len); - } -} - -#ifdef SH_HISTORY -int shItemCmp( void *val, void *idata ) -{ - return( (strcmp( val, idata ) == 0) ); -} -#endif - -static void *stdin_read_thread(void *x) -{ - int fd, fdi; - unsigned char buf[1024]; -#ifdef SH_HISTORY - unsigned char realbuf[1024], *buf_ptr; - SHLIST history; - SHLIST *item = &history; - int cmdlen = 0, ins_flag = 0; -#endif - int r, n; - int state = 0; - - int *fds = (int*) x; - fd = fds[0]; - fdi = fds[1]; - free(fds); - -#ifdef SH_HISTORY - shListInitList( &history ); -#endif - for(;;) { - /* fdi is really the client's stdin, so use read, not adb_read here */ - r = unix_read(fdi, buf, 1024); - if(r == 0) break; - if(r < 0) { - if(errno == EINTR) continue; - break; - } -#ifdef SH_HISTORY - if( (r == 3) && /* Arrow processing */ - (memcmp( (void *)buf, SH_ARROW_ANY, 2 ) == 0) ) { - switch( buf[2] ) { - case SH_ARROW_UP: - item = shListGetNextItem( &history, item ); - break; - case SH_ARROW_DOWN: - item = shListGetPrevItem( &history, item ); - break; - default: - item = NULL; - break; - } - memset( buf, SH_DEL_CHAR, cmdlen ); - if( item != NULL ) { - n = snprintf( (char *)(&buf[cmdlen]), sizeof buf - cmdlen, "%s", (char *)(item->data) ); - memcpy( realbuf, item->data, n ); - } - else { /* Clean buffer */ - item = &history; - n = 0; - } - r = n + cmdlen; - cmdlen = n; - ins_flag = 0; - if( r == 0 ) - continue; - } - else { -#endif - for(n = 0; n < r; n++){ - switch(buf[n]) { - case '\n': -#ifdef SH_HISTORY - if( ins_flag && (SH_BLANK_CHAR <= realbuf[0]) ) { - buf_ptr = malloc(cmdlen + 1); - if( buf_ptr != NULL ) { - memcpy( buf_ptr, realbuf, cmdlen ); - buf_ptr[cmdlen] = '\0'; - if( (item = shListFindItem( &history, (void *)buf_ptr, shItemCmp )) == NULL ) { - shListInsFirstItem( &history, (void *)buf_ptr ); - item = &history; - } - } - } - cmdlen = 0; - ins_flag = 0; -#endif - state = 1; - break; - case '\r': - state = 1; - break; - case '~': - if(state == 1) state++; - break; - case '.': - if(state == 2) { - fprintf(stderr,"\n* disconnect *\n"); - #ifdef HAVE_TERMIO_H - stdin_raw_restore(fdi); - #endif - exit(0); - } - default: -#ifdef SH_HISTORY - if( buf[n] == SH_DEL_CHAR ) { - if( cmdlen > 0 ) - cmdlen--; - } - else { - realbuf[cmdlen] = buf[n]; - cmdlen++; - } - ins_flag = 1; -#endif - state = 0; - } - } -#ifdef SH_HISTORY - } -#endif - r = adb_write(fd, buf, r); - if(r <= 0) { - break; - } - } -#ifdef SH_HISTORY - shListDelAllItems( &history, (shListFree)free ); -#endif - return 0; -} - -int interactive_shell(void) -{ - adb_thread_t thr; - int fdi, fd; - int *fds; - - fd = adb_connect("shell:"); - if(fd < 0) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - fdi = 0; //dup(0); - - fds = malloc(sizeof(int) * 2); - fds[0] = fd; - fds[1] = fdi; - -#ifdef HAVE_TERMIO_H - stdin_raw_init(fdi); -#endif - adb_thread_create(&thr, stdin_read_thread, fds); - read_and_dump(fd); -#ifdef HAVE_TERMIO_H - stdin_raw_restore(fdi); -#endif - return 0; -} - - -static void format_host_command(char* buffer, size_t buflen, const char* command, transport_type ttype, const char* serial) -{ - if (serial) { - snprintf(buffer, buflen, "host-serial:%s:%s", serial, command); - } else { - const char* prefix = "host"; - if (ttype == kTransportUsb) - prefix = "host-usb"; - else if (ttype == kTransportLocal) - prefix = "host-local"; - - snprintf(buffer, buflen, "%s:%s", prefix, command); - } -} - -static void status_window(transport_type ttype, const char* serial) -{ - char command[4096]; - char *state = 0; - char *laststate = 0; - - /* silence stderr */ -#ifdef _WIN32 - /* XXX: TODO */ -#else - int fd; - fd = unix_open("/dev/null", O_WRONLY); - dup2(fd, 2); - adb_close(fd); -#endif - - format_host_command(command, sizeof command, "get-state", ttype, serial); - - for(;;) { - adb_sleep_ms(250); - - if(state) { - free(state); - state = 0; - } - - state = adb_query(command); - - if(state) { - if(laststate && !strcmp(state,laststate)){ - continue; - } else { - if(laststate) free(laststate); - laststate = strdup(state); - } - } - - printf("%c[2J%c[2H", 27, 27); - printf("Android Debug Bridge\n"); - printf("State: %s\n", state ? state : "offline"); - fflush(stdout); - } -} - -/** duplicate string and quote all \ " ( ) chars + space character. */ -static char * -dupAndQuote(const char *s) -{ - const char *ts; - size_t alloc_len; - char *ret; - char *dest; - - ts = s; - - alloc_len = 0; - - for( ;*ts != '\0'; ts++) { - alloc_len++; - if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { - alloc_len++; - } - } - - ret = (char *)malloc(alloc_len + 1); - - ts = s; - dest = ret; - - for ( ;*ts != '\0'; ts++) { - if (*ts == ' ' || *ts == '"' || *ts == '\\' || *ts == '(' || *ts == ')') { - *dest++ = '\\'; - } - - *dest++ = *ts; - } - - *dest++ = '\0'; - - return ret; -} - -/** - * Run ppp in "notty" mode against a resource listed as the first parameter - * eg: - * - * ppp dev:/dev/omap_csmi_tty0 <ppp options> - * - */ -int ppp(int argc, char **argv) -{ -#ifdef HAVE_WIN32_PROC - fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]); - return -1; -#else - char *adb_service_name; - pid_t pid; - int fd; - - if (argc < 2) { - fprintf(stderr, "usage: adb %s <adb service name> [ppp opts]\n", - argv[0]); - - return 1; - } - - adb_service_name = argv[1]; - - fd = adb_connect(adb_service_name); - - if(fd < 0) { - fprintf(stderr,"Error: Could not open adb service: %s. Error: %s\n", - adb_service_name, adb_error()); - return 1; - } - - pid = fork(); - - if (pid < 0) { - perror("from fork()"); - return 1; - } else if (pid == 0) { - int err; - int i; - const char **ppp_args; - - // copy args - ppp_args = (const char **) alloca(sizeof(char *) * argc + 1); - ppp_args[0] = "pppd"; - for (i = 2 ; i < argc ; i++) { - //argv[2] and beyond become ppp_args[1] and beyond - ppp_args[i - 1] = argv[i]; - } - ppp_args[i-1] = NULL; - - // child side - - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - adb_close(STDERR_FILENO); - adb_close(fd); - - err = execvp("pppd", (char * const *)ppp_args); - - if (err < 0) { - perror("execing pppd"); - } - exit(-1); - } else { - // parent side - - adb_close(fd); - return 0; - } -#endif /* !HAVE_WIN32_PROC */ -} - -static int send_shellcommand(transport_type transport, char* serial, char* buf) -{ - int fd, ret; - - for(;;) { - fd = adb_connect(buf); - if(fd >= 0) - break; - fprintf(stderr,"- waiting for device -\n"); - adb_sleep_ms(1000); - do_cmd(transport, serial, "wait-for-device", 0); - } - - read_and_dump(fd); - ret = adb_close(fd); - if (ret) - perror("close"); - - return ret; -} - -static int logcat(transport_type transport, char* serial, int argc, char **argv) -{ - char buf[4096]; - - char *log_tags; - char *quoted_log_tags; - - log_tags = getenv("ANDROID_LOG_TAGS"); - quoted_log_tags = dupAndQuote(log_tags == NULL ? "" : log_tags); - - snprintf(buf, sizeof(buf), - "shell:export ANDROID_LOG_TAGS=\"\%s\" ; exec logcat", - quoted_log_tags); - - free(quoted_log_tags); - - argc -= 1; - argv += 1; - while(argc-- > 0) { - char *quoted; - - quoted = dupAndQuote (*argv++); - - strncat(buf, " ", sizeof(buf)-1); - strncat(buf, quoted, sizeof(buf)-1); - free(quoted); - } - - send_shellcommand(transport, serial, buf); - return 0; -} - -#define SENTINEL_FILE "config" OS_PATH_SEPARATOR_STR "envsetup.make" -static int top_works(const char *top) -{ - if (top != NULL && adb_is_absolute_host_path(top)) { - char path_buf[PATH_MAX]; - snprintf(path_buf, sizeof(path_buf), - "%s" OS_PATH_SEPARATOR_STR SENTINEL_FILE, top); - return access(path_buf, F_OK) == 0; - } - return 0; -} - -static char *find_top_from(const char *indir, char path_buf[PATH_MAX]) -{ - strcpy(path_buf, indir); - while (1) { - if (top_works(path_buf)) { - return path_buf; - } - char *s = adb_dirstop(path_buf); - if (s != NULL) { - *s = '\0'; - } else { - path_buf[0] = '\0'; - return NULL; - } - } -} - -static char *find_top(char path_buf[PATH_MAX]) -{ - char *top = getenv("ANDROID_BUILD_TOP"); - if (top != NULL && top[0] != '\0') { - if (!top_works(top)) { - fprintf(stderr, "adb: bad ANDROID_BUILD_TOP value \"%s\"\n", top); - return NULL; - } - } else { - top = getenv("TOP"); - if (top != NULL && top[0] != '\0') { - if (!top_works(top)) { - fprintf(stderr, "adb: bad TOP value \"%s\"\n", top); - return NULL; - } - } else { - top = NULL; - } - } - - if (top != NULL) { - /* The environment pointed to a top directory that works. - */ - strcpy(path_buf, top); - return path_buf; - } - - /* The environment didn't help. Walk up the tree from the CWD - * to see if we can find the top. - */ - char dir[PATH_MAX]; - top = find_top_from(getcwd(dir, sizeof(dir)), path_buf); - if (top == NULL) { - /* If the CWD isn't under a good-looking top, see if the - * executable is. - */ - get_my_path(dir); - top = find_top_from(dir, path_buf); - } - return top; -} - -/* <hint> may be: - * - A simple product name - * e.g., "sooner" -TODO: debug? sooner-debug, sooner:debug? - * - A relative path from the CWD to the ANDROID_PRODUCT_OUT dir - * e.g., "out/target/product/sooner" - * - An absolute path to the PRODUCT_OUT dir - * e.g., "/src/device/out/target/product/sooner" - * - * Given <hint>, try to construct an absolute path to the - * ANDROID_PRODUCT_OUT dir. - */ -static const char *find_product_out_path(const char *hint) -{ - static char path_buf[PATH_MAX]; - - if (hint == NULL || hint[0] == '\0') { - return NULL; - } - - /* If it's already absolute, don't bother doing any work. - */ - if (adb_is_absolute_host_path(hint)) { - strcpy(path_buf, hint); - return path_buf; - } - - /* If there are any slashes in it, assume it's a relative path; - * make it absolute. - */ - if (adb_dirstart(hint) != NULL) { - if (getcwd(path_buf, sizeof(path_buf)) == NULL) { - fprintf(stderr, "adb: Couldn't get CWD: %s\n", strerror(errno)); - return NULL; - } - if (strlen(path_buf) + 1 + strlen(hint) >= sizeof(path_buf)) { - fprintf(stderr, "adb: Couldn't assemble path\n"); - return NULL; - } - strcat(path_buf, OS_PATH_SEPARATOR_STR); - strcat(path_buf, hint); - return path_buf; - } - - /* It's a string without any slashes. Try to do something with it. - * - * Try to find the root of the build tree, and build a PRODUCT_OUT - * path from there. - */ - char top_buf[PATH_MAX]; - const char *top = find_top(top_buf); - if (top == NULL) { - fprintf(stderr, "adb: Couldn't find top of build tree\n"); - return NULL; - } -//TODO: if we have a way to indicate debug, look in out/debug/target/... - snprintf(path_buf, sizeof(path_buf), - "%s" OS_PATH_SEPARATOR_STR - "out" OS_PATH_SEPARATOR_STR - "target" OS_PATH_SEPARATOR_STR - "product" OS_PATH_SEPARATOR_STR - "%s", top_buf, hint); - if (access(path_buf, F_OK) < 0) { - fprintf(stderr, "adb: Couldn't find a product dir " - "based on \"-p %s\"; \"%s\" doesn't exist\n", hint, path_buf); - return NULL; - } - return path_buf; -} - -int adb_commandline(int argc, char **argv) -{ - char buf[4096]; - int no_daemon = 0; - int is_daemon = 0; - int persist = 0; - int r; - int quote; - transport_type ttype = kTransportAny; - char* serial = NULL; - - /* If defined, this should be an absolute path to - * the directory containing all of the various system images - * for a particular product. If not defined, and the adb - * command requires this information, then the user must - * specify the path using "-p". - */ - gProductOutPath = getenv("ANDROID_PRODUCT_OUT"); - if (gProductOutPath == NULL || gProductOutPath[0] == '\0') { - gProductOutPath = NULL; - } - // TODO: also try TARGET_PRODUCT/TARGET_DEVICE as a hint - - /* modifiers and flags */ - while(argc > 0) { - if(!strcmp(argv[0],"nodaemon")) { - no_daemon = 1; - } else if (!strcmp(argv[0], "fork-server")) { - /* this is a special flag used only when the ADB client launches the ADB Server */ - is_daemon = 1; - } else if(!strcmp(argv[0],"persist")) { - persist = 1; - } else if(!strncmp(argv[0], "-p", 2)) { - const char *product = NULL; - if (argv[0][2] == '\0') { - if (argc < 2) return usage(); - product = argv[1]; - argc--; - argv++; - } else { - product = argv[1] + 2; - } - gProductOutPath = find_product_out_path(product); - if (gProductOutPath == NULL) { - fprintf(stderr, "adb: could not resolve \"-p %s\"\n", - product); - return usage(); - } - } else if (argv[0][0]=='-' && argv[0][1]=='s') { - if (isdigit(argv[0][2])) { - serial = argv[0] + 2; - } else { - if(argc < 2) return usage(); - serial = argv[1]; - argc--; - argv++; - } - } else if (!strcmp(argv[0],"-d")) { - ttype = kTransportUsb; - } else if (!strcmp(argv[0],"-e")) { - ttype = kTransportLocal; - } else { - /* out of recognized modifiers and flags */ - break; - } - argc--; - argv++; - } - - adb_set_transport(ttype, serial); - - if ((argc > 0) && (!strcmp(argv[0],"server"))) { - if (no_daemon || is_daemon) { - r = adb_main(is_daemon); - } else { - r = launch_server(); - } - if(r) { - fprintf(stderr,"* could not start server *\n"); - } - return r; - } - -top: - if(argc == 0) { - return usage(); - } - - /* adb_connect() commands */ - - if(!strcmp(argv[0], "devices")) { - char *tmp; - snprintf(buf, sizeof buf, "host:%s", argv[0]); - tmp = adb_query(buf); - if(tmp) { - printf("List of devices attached \n"); - printf("%s\n", tmp); - return 0; - } else { - return 1; - } - } - - if (!strcmp(argv[0], "emu")) { - return adb_send_emulator_command(argc, argv); - } - - if(!strcmp(argv[0], "shell")) { - int r; - int fd; - - if(argc < 2) { - return interactive_shell(); - } - - snprintf(buf, sizeof buf, "shell:%s", argv[1]); - argc -= 2; - argv += 2; - while(argc-- > 0) { - strcat(buf, " "); - - /* quote empty strings and strings with spaces */ - quote = (**argv == 0 || strchr(*argv, ' ')); - if (quote) - strcat(buf, "\""); - strcat(buf, *argv++); - if (quote) - strcat(buf, "\""); - } - - for(;;) { - fd = adb_connect(buf); - if(fd >= 0) { - read_and_dump(fd); - adb_close(fd); - r = 0; - } else { - fprintf(stderr,"error: %s\n", adb_error()); - r = -1; - } - - if(persist) { - fprintf(stderr,"\n- waiting for device -\n"); - adb_sleep_ms(1000); - do_cmd(ttype, serial, "wait-for-device", 0); - } else { - return r; - } - } - } - - if(!strcmp(argv[0], "kill-server")) { - int fd; - fd = _adb_connect("host:kill"); - if(fd == -1) { - fprintf(stderr,"* server not running *\n"); - return 1; - } - return 0; - } - - if(!strcmp(argv[0], "remount")) { - int fd = adb_connect("remount:"); - if(fd >= 0) { - read_and_dump(fd); - adb_close(fd); - return 0; - } - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - if(!strcmp(argv[0], "bugreport")) { - if (argc != 1) { - return 1; - } - do_cmd(ttype, serial, "shell", "dumpstate", "-", 0); - return 0; - } - - /* adb_command() wrapper commands */ - - if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) { - char* service = argv[0]; - if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) { - if (ttype == kTransportUsb) { - service = "wait-for-usb"; - } else if (ttype == kTransportLocal) { - service = "wait-for-local"; - } else { - service = "wait-for-any"; - } - } - - format_host_command(buf, sizeof buf, service, ttype, serial); - - if (adb_command(buf)) { - D("failure: %s *\n",adb_error()); - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - /* Allow a command to be run after wait-for-device, - * e.g. 'adb wait-for-device shell'. - */ - if(argc > 1) { - argc--; - argv++; - goto top; - } - return 0; - } - - if(!strcmp(argv[0], "forward")) { - if(argc != 3) return usage(); - if (serial) { - snprintf(buf, sizeof buf, "host-serial:%s:forward:%s;%s",serial,argv[1],argv[2]); - } else { - snprintf(buf, sizeof buf, "host:forward:%s;%s",argv[1],argv[2]); - } - if(adb_command(buf)) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - return 0; - } - - /* do_sync_*() commands */ - - if(!strcmp(argv[0], "ls")) { - if(argc != 2) return usage(); - return do_sync_ls(argv[1]); - } - - if(!strcmp(argv[0], "push")) { - if(argc != 3) return usage(); - return do_sync_push(argv[1], argv[2], 0 /* no verify APK */); - } - - if(!strcmp(argv[0], "pull")) { - if(argc != 3) return usage(); - return do_sync_pull(argv[1], argv[2]); - } - - if(!strcmp(argv[0], "install")) { - if (argc < 2) return usage(); - return install_app(ttype, serial, argc, argv); - } - - if(!strcmp(argv[0], "uninstall")) { - if (argc < 2) return usage(); - return uninstall_app(ttype, serial, argc, argv); - } - - if(!strcmp(argv[0], "sync")) { - char *srcarg, *android_srcpath, *data_srcpath; - int ret; - if(argc < 2) { - /* No local path was specified. */ - srcarg = NULL; - } else if(argc == 2) { - /* A local path or "android"/"data" arg was specified. */ - srcarg = argv[1]; - } else { - return usage(); - } - ret = find_sync_dirs(srcarg, &android_srcpath, &data_srcpath); - if(ret != 0) return usage(); - - if(android_srcpath != NULL) - ret = do_sync_sync(android_srcpath, "/system"); - if(ret == 0 && data_srcpath != NULL) - ret = do_sync_sync(data_srcpath, "/data"); - - free(android_srcpath); - free(data_srcpath); - return ret; - } - - /* passthrough commands */ - - if(!strcmp(argv[0],"get-state") || - !strcmp(argv[0],"get-serialno")) - { - char *tmp; - - format_host_command(buf, sizeof buf, argv[0], ttype, serial); - tmp = adb_query(buf); - if(tmp) { - printf("%s\n", tmp); - return 0; - } else { - return 1; - } - } - - /* other commands */ - - if(!strcmp(argv[0],"status-window")) { - status_window(ttype, serial); - return 0; - } - - if(!strcmp(argv[0],"logcat") || !strcmp(argv[0],"lolcat")) { - return logcat(ttype, serial, argc, argv); - } - - if(!strcmp(argv[0],"ppp")) { - return ppp(argc, argv); - } - - if (!strcmp(argv[0], "start-server")) { - return adb_connect("host:start-server"); - } - - if (!strcmp(argv[0], "jdwp")) { - int fd = adb_connect("jdwp"); - if (fd >= 0) { - read_and_dump(fd); - adb_close(fd); - return 0; - } else { - fprintf(stderr, "error: %s\n", adb_error()); - return -1; - } - } - - /* "adb /?" is a common idiom under Windows */ - if(!strcmp(argv[0], "help") || !strcmp(argv[0], "/?")) { - help(); - return 0; - } - - if(!strcmp(argv[0], "version")) { - version(stdout); - return 0; - } - - usage(); - return 1; -} - -static int do_cmd(transport_type ttype, char* serial, char *cmd, ...) -{ - char *argv[16]; - int argc; - va_list ap; - - va_start(ap, cmd); - argc = 0; - - if (serial) { - argv[argc++] = "-s"; - argv[argc++] = serial; - } else if (ttype == kTransportUsb) { - argv[argc++] = "-d"; - } else if (ttype == kTransportLocal) { - argv[argc++] = "-e"; - } - - argv[argc++] = cmd; - while((argv[argc] = va_arg(ap, char*)) != 0) argc++; - va_end(ap); - -#if 0 - int n; - fprintf(stderr,"argc = %d\n",argc); - for(n = 0; n < argc; n++) { - fprintf(stderr,"argv[%d] = \"%s\"\n", n, argv[n]); - } -#endif - - return adb_commandline(argc, argv); -} - -int find_sync_dirs(const char *srcarg, - char **android_srcdir_out, char **data_srcdir_out) -{ - char *android_srcdir, *data_srcdir; - - if(srcarg == NULL) { - android_srcdir = product_file("system"); - data_srcdir = product_file("data"); - } else { - /* srcarg may be "data", "system" or NULL. - * if srcarg is NULL, then both data and system are synced - */ - if(strcmp(srcarg, "system") == 0) { - android_srcdir = product_file("system"); - data_srcdir = NULL; - } else if(strcmp(srcarg, "data") == 0) { - android_srcdir = NULL; - data_srcdir = product_file("data"); - } else { - /* It's not "system" or "data". - */ - return 1; - } - } - - if(android_srcdir_out != NULL) - *android_srcdir_out = android_srcdir; - else - free(android_srcdir); - - if(data_srcdir_out != NULL) - *data_srcdir_out = data_srcdir; - else - free(data_srcdir); - - return 0; -} - -static int pm_command(transport_type transport, char* serial, - int argc, char** argv) -{ - char buf[4096]; - - snprintf(buf, sizeof(buf), "shell:pm"); - - while(argc-- > 0) { - char *quoted; - - quoted = dupAndQuote(*argv++); - - strncat(buf, " ", sizeof(buf)-1); - strncat(buf, quoted, sizeof(buf)-1); - free(quoted); - } - - send_shellcommand(transport, serial, buf); - return 0; -} - -int uninstall_app(transport_type transport, char* serial, int argc, char** argv) -{ - /* if the user choose the -k option, we refuse to do it until devices are - out with the option to uninstall the remaining data somehow (adb/ui) */ - if (argc == 3 && strcmp(argv[1], "-k") == 0) - { - printf( - "The -k option uninstalls the application while retaining the data/cache.\n" - "At the moment, there is no way to remove the remaining data.\n" - "You will have to reinstall the application with the same signature, and fully uninstall it.\n" - "If you truly wish to continue, execute 'adb shell pm uninstall -k %s'\n", argv[2]); - return -1; - } - - /* 'adb uninstall' takes the same arguments as 'pm uninstall' on device */ - return pm_command(transport, serial, argc, argv); -} - -static int delete_file(transport_type transport, char* serial, char* filename) -{ - char buf[4096]; - char* quoted; - - snprintf(buf, sizeof(buf), "shell:rm "); - quoted = dupAndQuote(filename); - strncat(buf, quoted, sizeof(buf)-1); - free(quoted); - - send_shellcommand(transport, serial, buf); - return 0; -} - -int install_app(transport_type transport, char* serial, int argc, char** argv) -{ - struct stat st; - int err; - const char *const WHERE = "/data/local/tmp/%s"; - char to[PATH_MAX]; - char* filename = argv[argc - 1]; - const char* p; - - p = adb_dirstop(filename); - if (p) { - p++; - snprintf(to, sizeof to, WHERE, p); - } else { - snprintf(to, sizeof to, WHERE, filename); - } - if (p[0] == '\0') { - } - - err = stat(filename, &st); - if (err != 0) { - fprintf(stderr, "can't find '%s' to install\n", filename); - return 1; - } - if (!S_ISREG(st.st_mode)) { - fprintf(stderr, "can't install '%s' because it's not a file\n", - filename); - return 1; - } - - if (!(err = do_sync_push(filename, to, 1 /* verify APK */))) { - /* file in place; tell the Package Manager to install it */ - argv[argc - 1] = to; /* destination name, not source location */ - pm_command(transport, serial, argc, argv); - delete_file(transport, serial, to); - } - - return err; -} diff --git a/adb/console.c b/adb/console.c deleted file mode 100644 index b813d337dedcb08ed6c8922b795c4c2405c479b5..0000000000000000000000000000000000000000 --- a/adb/console.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "sysdeps.h" -#include "adb.h" -#include "adb_client.h" -#include <stdio.h> - -static int connect_to_console(void) -{ - int fd, port; - - port = adb_get_emulator_console_port(); - if (port < 0) { - if (port == -2) - fprintf(stderr, "error: more than one emulator detected. use -s option\n"); - else - fprintf(stderr, "error: no emulator detected\n"); - return -1; - } - fd = socket_loopback_client( port, SOCK_STREAM ); - if (fd < 0) { - fprintf(stderr, "error: could not connect to TCP port %d\n", port); - return -1; - } - return fd; -} - - -int adb_send_emulator_command(int argc, char** argv) -{ - int fd, nn; - - fd = connect_to_console(); - if (fd < 0) - return 1; - -#define QUIT "quit\n" - - for (nn = 1; nn < argc; nn++) { - adb_write( fd, argv[nn], strlen(argv[nn]) ); - adb_write( fd, (nn == argc-1) ? "\n" : " ", 1 ); - } - adb_write( fd, QUIT, sizeof(QUIT)-1 ); - adb_close(fd); - - return 0; -} diff --git a/adb/file_sync_client.c b/adb/file_sync_client.c deleted file mode 100644 index 4e6d385918808882e338f2e8895186c907c5e2e4..0000000000000000000000000000000000000000 --- a/adb/file_sync_client.c +++ /dev/null @@ -1,1022 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <time.h> -#include <dirent.h> -#include <limits.h> -#include <sys/types.h> -#include <zipfile/zipfile.h> - -#include "sysdeps.h" -#include "adb.h" -#include "adb_client.h" -#include "file_sync_service.h" - - -static unsigned total_bytes; -static long long start_time; - -static long long NOW() -{ - struct timeval tv; - gettimeofday(&tv, 0); - return ((long long) tv.tv_usec) + - 1000000LL * ((long long) tv.tv_sec); -} - -static void BEGIN() -{ - total_bytes = 0; - start_time = NOW(); -} - -static void END() -{ - long long t = NOW() - start_time; - if(total_bytes == 0) return; - - if (t == 0) /* prevent division by 0 :-) */ - t = 1000000; - - fprintf(stderr,"%lld KB/s (%d bytes in %lld.%03llds)\n", - ((((long long) total_bytes) * 1000000LL) / t) / 1024LL, - total_bytes, (t / 1000000LL), (t % 1000000LL) / 1000LL); -} - -void sync_quit(int fd) -{ - syncmsg msg; - - msg.req.id = ID_QUIT; - msg.req.namelen = 0; - - writex(fd, &msg.req, sizeof(msg.req)); -} - -typedef void (*sync_ls_cb)(unsigned mode, unsigned size, unsigned time, const char *name, void *cookie); - -int sync_ls(int fd, const char *path, sync_ls_cb func, void *cookie) -{ - syncmsg msg; - char buf[257]; - int len; - - len = strlen(path); - if(len > 1024) goto fail; - - msg.req.id = ID_LIST; - msg.req.namelen = htoll(len); - - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, path, len)) { - goto fail; - } - - for(;;) { - if(readx(fd, &msg.dent, sizeof(msg.dent))) break; - if(msg.dent.id == ID_DONE) return 0; - if(msg.dent.id != ID_DENT) break; - - len = ltohl(msg.dent.namelen); - if(len > 256) break; - - if(readx(fd, buf, len)) break; - buf[len] = 0; - - func(ltohl(msg.dent.mode), - ltohl(msg.dent.size), - ltohl(msg.dent.time), - buf, cookie); - } - -fail: - adb_close(fd); - return -1; -} - -typedef struct syncsendbuf syncsendbuf; - -struct syncsendbuf { - unsigned id; - unsigned size; - char data[SYNC_DATA_MAX]; -}; - -static syncsendbuf send_buffer; - -int sync_readtime(int fd, const char *path, unsigned *timestamp) -{ - syncmsg msg; - int len = strlen(path); - - msg.req.id = ID_STAT; - msg.req.namelen = htoll(len); - - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, path, len)) { - return -1; - } - - if(readx(fd, &msg.stat, sizeof(msg.stat))) { - return -1; - } - - if(msg.stat.id != ID_STAT) { - return -1; - } - - *timestamp = ltohl(msg.stat.time); - return 0; -} - -static int sync_start_readtime(int fd, const char *path) -{ - syncmsg msg; - int len = strlen(path); - - msg.req.id = ID_STAT; - msg.req.namelen = htoll(len); - - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, path, len)) { - return -1; - } - - return 0; -} - -static int sync_finish_readtime(int fd, unsigned int *timestamp, - unsigned int *mode, unsigned int *size) -{ - syncmsg msg; - - if(readx(fd, &msg.stat, sizeof(msg.stat))) - return -1; - - if(msg.stat.id != ID_STAT) - return -1; - - *timestamp = ltohl(msg.stat.time); - *mode = ltohl(msg.stat.mode); - *size = ltohl(msg.stat.size); - - return 0; -} - -int sync_readmode(int fd, const char *path, unsigned *mode) -{ - syncmsg msg; - int len = strlen(path); - - msg.req.id = ID_STAT; - msg.req.namelen = htoll(len); - - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, path, len)) { - return -1; - } - - if(readx(fd, &msg.stat, sizeof(msg.stat))) { - return -1; - } - - if(msg.stat.id != ID_STAT) { - return -1; - } - - *mode = ltohl(msg.stat.mode); - return 0; -} - -static int write_data_file(int fd, const char *path, syncsendbuf *sbuf) -{ - int lfd, err = 0; - - lfd = adb_open(path, O_RDONLY); - if(lfd < 0) { - fprintf(stderr,"cannot open '%s': %s\n", path, strerror(errno)); - return -1; - } - - sbuf->id = ID_DATA; - for(;;) { - int ret; - - ret = adb_read(lfd, sbuf->data, SYNC_DATA_MAX); - if(!ret) - break; - - if(ret < 0) { - if(errno == EINTR) - continue; - fprintf(stderr,"cannot read '%s': %s\n", path, strerror(errno)); - break; - } - - sbuf->size = htoll(ret); - if(writex(fd, sbuf, sizeof(unsigned) * 2 + ret)){ - err = -1; - break; - } - total_bytes += ret; - } - - adb_close(lfd); - return err; -} - -static int write_data_buffer(int fd, char* file_buffer, int size, syncsendbuf *sbuf) -{ - int err = 0; - int total = 0; - - sbuf->id = ID_DATA; - while (total < size) { - int count = size - total; - if (count > SYNC_DATA_MAX) { - count = SYNC_DATA_MAX; - } - - memcpy(sbuf->data, &file_buffer[total], count); - sbuf->size = htoll(count); - if(writex(fd, sbuf, sizeof(unsigned) * 2 + count)){ - err = -1; - break; - } - total += count; - total_bytes += count; - } - - return err; -} - -#ifdef HAVE_SYMLINKS -static int write_data_link(int fd, const char *path, syncsendbuf *sbuf) -{ - int len, ret; - - len = readlink(path, sbuf->data, SYNC_DATA_MAX-1); - if(len < 0) { - fprintf(stderr, "error reading link '%s': %s\n", path, strerror(errno)); - return -1; - } - sbuf->data[len] = '\0'; - - sbuf->size = htoll(len + 1); - sbuf->id = ID_DATA; - - ret = writex(fd, sbuf, sizeof(unsigned) * 2 + len + 1); - if(ret) - return -1; - - total_bytes += len + 1; - - return 0; -} -#endif - -static int sync_send(int fd, const char *lpath, const char *rpath, - unsigned mtime, mode_t mode, int verifyApk) -{ - syncmsg msg; - int len, r; - syncsendbuf *sbuf = &send_buffer; - char* file_buffer = NULL; - int size = 0; - char tmp[64]; - - len = strlen(rpath); - if(len > 1024) goto fail; - - snprintf(tmp, sizeof(tmp), ",%d", mode); - r = strlen(tmp); - - if (verifyApk) { - int lfd; - zipfile_t zip; - zipentry_t entry; - int amt; - - // if we are transferring an APK file, then sanity check to make sure - // we have a real zip file that contains an AndroidManifest.xml - // this requires that we read the entire file into memory. - lfd = adb_open(lpath, O_RDONLY); - if(lfd < 0) { - fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno)); - return -1; - } - - size = adb_lseek(lfd, 0, SEEK_END); - if (size == -1 || -1 == adb_lseek(lfd, 0, SEEK_SET)) { - fprintf(stderr, "error seeking in file '%s'\n", lpath); - adb_close(lfd); - return 1; - } - - file_buffer = (char *)malloc(size); - if (file_buffer == NULL) { - fprintf(stderr, "could not allocate buffer for '%s'\n", - lpath); - adb_close(lfd); - return 1; - } - amt = adb_read(lfd, file_buffer, size); - if (amt != size) { - fprintf(stderr, "error reading from file: '%s'\n", lpath); - adb_close(lfd); - free(file_buffer); - return 1; - } - - adb_close(lfd); - - zip = init_zipfile(file_buffer, size); - if (zip == NULL) { - fprintf(stderr, "file '%s' is not a valid zip file\n", - lpath); - free(file_buffer); - return 1; - } - - entry = lookup_zipentry(zip, "AndroidManifest.xml"); - release_zipfile(zip); - if (entry == NULL) { - fprintf(stderr, "file '%s' does not contain AndroidManifest.xml\n", - lpath); - free(file_buffer); - return 1; - } - } - - msg.req.id = ID_SEND; - msg.req.namelen = htoll(len + r); - - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, rpath, len) || writex(fd, tmp, r)) { - free(file_buffer); - goto fail; - } - - if (file_buffer) { - write_data_buffer(fd, file_buffer, size, sbuf); - free(file_buffer); - } else if (S_ISREG(mode)) - write_data_file(fd, lpath, sbuf); -#ifdef HAVE_SYMLINKS - else if (S_ISLNK(mode)) - write_data_link(fd, lpath, sbuf); -#endif - else - goto fail; - - msg.data.id = ID_DONE; - msg.data.size = htoll(mtime); - if(writex(fd, &msg.data, sizeof(msg.data))) - goto fail; - - if(readx(fd, &msg.status, sizeof(msg.status))) - return -1; - - if(msg.status.id != ID_OKAY) { - if(msg.status.id == ID_FAIL) { - len = ltohl(msg.status.msglen); - if(len > 256) len = 256; - if(readx(fd, sbuf->data, len)) { - return -1; - } - sbuf->data[len] = 0; - } else - strcpy(sbuf->data, "unknown reason"); - - fprintf(stderr,"failed to copy '%s' to '%s': %s\n", lpath, rpath, sbuf->data); - return -1; - } - - return 0; - -fail: - fprintf(stderr,"protocol failure\n"); - adb_close(fd); - return -1; -} - -static int mkdirs(char *name) -{ - int ret; - char *x = name + 1; - - for(;;) { - x = adb_dirstart(x); - if(x == 0) return 0; - *x = 0; - ret = adb_mkdir(name, 0775); - *x = OS_PATH_SEPARATOR; - if((ret < 0) && (errno != EEXIST)) { - return ret; - } - x++; - } - return 0; -} - -int sync_recv(int fd, const char *rpath, const char *lpath) -{ - syncmsg msg; - int len; - int lfd = -1; - char *buffer = send_buffer.data; - unsigned id; - - len = strlen(rpath); - if(len > 1024) return -1; - - msg.req.id = ID_RECV; - msg.req.namelen = htoll(len); - if(writex(fd, &msg.req, sizeof(msg.req)) || - writex(fd, rpath, len)) { - return -1; - } - - if(readx(fd, &msg.data, sizeof(msg.data))) { - return -1; - } - id = msg.data.id; - - if((id == ID_DATA) || (id == ID_DONE)) { - adb_unlink(lpath); - mkdirs((char *)lpath); - lfd = adb_creat(lpath, 0644); - if(lfd < 0) { - fprintf(stderr,"cannot create '%s': %s\n", lpath, strerror(errno)); - return -1; - } - goto handle_data; - } else { - goto remote_error; - } - - for(;;) { - if(readx(fd, &msg.data, sizeof(msg.data))) { - return -1; - } - id = msg.data.id; - - handle_data: - len = ltohl(msg.data.size); - if(id == ID_DONE) break; - if(id != ID_DATA) goto remote_error; - if(len > SYNC_DATA_MAX) { - fprintf(stderr,"data overrun\n"); - adb_close(lfd); - return -1; - } - - if(readx(fd, buffer, len)) { - adb_close(lfd); - return -1; - } - - if(writex(lfd, buffer, len)) { - fprintf(stderr,"cannot write '%s': %s\n", rpath, strerror(errno)); - adb_close(lfd); - return -1; - } - - total_bytes += len; - } - - adb_close(lfd); - return 0; - -remote_error: - adb_close(lfd); - adb_unlink(lpath); - - if(id == ID_FAIL) { - len = ltohl(msg.data.size); - if(len > 256) len = 256; - if(readx(fd, buffer, len)) { - return -1; - } - buffer[len] = 0; - } else { - memcpy(buffer, &id, 4); - buffer[4] = 0; -// strcpy(buffer,"unknown reason"); - } - fprintf(stderr,"failed to copy '%s' to '%s': %s\n", rpath, lpath, buffer); - return 0; -} - - - -/* --- */ - - -static void do_sync_ls_cb(unsigned mode, unsigned size, unsigned time, - const char *name, void *cookie) -{ - printf("%08x %08x %08x %s\n", mode, size, time, name); -} - -int do_sync_ls(const char *path) -{ - int fd = adb_connect("sync:"); - if(fd < 0) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - if(sync_ls(fd, path, do_sync_ls_cb, 0)) { - return 1; - } else { - sync_quit(fd); - return 0; - } -} - -typedef struct copyinfo copyinfo; - -struct copyinfo -{ - copyinfo *next; - const char *src; - const char *dst; - unsigned int time; - unsigned int mode; - unsigned int size; - int flag; - //char data[0]; -}; - -copyinfo *mkcopyinfo(const char *spath, const char *dpath, - const char *name, int isdir) -{ - int slen = strlen(spath); - int dlen = strlen(dpath); - int nlen = strlen(name); - int ssize = slen + nlen + 2; - int dsize = dlen + nlen + 2; - - copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize); - if(ci == 0) { - fprintf(stderr,"out of memory\n"); - abort(); - } - - ci->next = 0; - ci->time = 0; - ci->mode = 0; - ci->size = 0; - ci->flag = 0; - ci->src = (const char*)(ci + 1); - ci->dst = ci->src + ssize; - snprintf((char*) ci->src, ssize, isdir ? "%s%s/" : "%s%s", spath, name); - snprintf((char*) ci->dst, dsize, isdir ? "%s%s/" : "%s%s", dpath, name); - -// fprintf(stderr,"mkcopyinfo('%s','%s')\n", ci->src, ci->dst); - return ci; -} - - -static int local_build_list(copyinfo **filelist, - const char *lpath, const char *rpath) -{ - DIR *d; - struct dirent *de; - struct stat st; - copyinfo *dirlist = 0; - copyinfo *ci, *next; - -// fprintf(stderr,"local_build_list('%s','%s')\n", lpath, rpath); - - d = opendir(lpath); - if(d == 0) { - fprintf(stderr,"cannot open '%s': %s\n", lpath, strerror(errno)); - return -1; - } - - while((de = readdir(d))) { - char stat_path[PATH_MAX]; - char *name = de->d_name; - - if(name[0] == '.') { - if(name[1] == 0) continue; - if((name[1] == '.') && (name[2] == 0)) continue; - } - - /* - * We could use d_type if HAVE_DIRENT_D_TYPE is defined, but reiserfs - * always returns DT_UNKNOWN, so we just use stat() for all cases. - */ - if (strlen(lpath) + strlen(de->d_name) + 1 > sizeof(stat_path)) - continue; - strcpy(stat_path, lpath); - strcat(stat_path, de->d_name); - stat(stat_path, &st); - - if (S_ISDIR(st.st_mode)) { - ci = mkcopyinfo(lpath, rpath, name, 1); - ci->next = dirlist; - dirlist = ci; - } else { - ci = mkcopyinfo(lpath, rpath, name, 0); - if(lstat(ci->src, &st)) { - closedir(d); - fprintf(stderr,"cannot stat '%s': %s\n", ci->src, strerror(errno)); - return -1; - } - if(!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) { - fprintf(stderr, "skipping special file '%s'\n", ci->src); - free(ci); - } else { - ci->time = st.st_mtime; - ci->mode = st.st_mode; - ci->size = st.st_size; - ci->next = *filelist; - *filelist = ci; - } - } - } - - closedir(d); - - for(ci = dirlist; ci != 0; ci = next) { - next = ci->next; - local_build_list(filelist, ci->src, ci->dst); - free(ci); - } - - return 0; -} - - -static int copy_local_dir_remote(int fd, const char *lpath, const char *rpath, int checktimestamps) -{ - copyinfo *filelist = 0; - copyinfo *ci, *next; - int pushed = 0; - int skipped = 0; - - if((lpath[0] == 0) || (rpath[0] == 0)) return -1; - if(lpath[strlen(lpath) - 1] != '/') { - int tmplen = strlen(lpath)+2; - char *tmp = malloc(tmplen); - if(tmp == 0) return -1; - snprintf(tmp, tmplen, "%s/",lpath); - lpath = tmp; - } - if(rpath[strlen(rpath) - 1] != '/') { - int tmplen = strlen(rpath)+2; - char *tmp = malloc(tmplen); - if(tmp == 0) return -1; - snprintf(tmp, tmplen, "%s/",rpath); - rpath = tmp; - } - - if(local_build_list(&filelist, lpath, rpath)) { - return -1; - } - - if(checktimestamps){ - for(ci = filelist; ci != 0; ci = ci->next) { - if(sync_start_readtime(fd, ci->dst)) { - return 1; - } - } - for(ci = filelist; ci != 0; ci = ci->next) { - unsigned int timestamp, mode, size; - if(sync_finish_readtime(fd, ×tamp, &mode, &size)) - return 1; - if(size == ci->size) { - /* for links, we cannot update the atime/mtime */ - if((S_ISREG(ci->mode & mode) && timestamp == ci->time) || - (S_ISLNK(ci->mode & mode) && timestamp >= ci->time)) - ci->flag = 1; - } - } - } - for(ci = filelist; ci != 0; ci = next) { - next = ci->next; - if(ci->flag == 0) { - fprintf(stderr,"push: %s -> %s\n", ci->src, ci->dst); - if(sync_send(fd, ci->src, ci->dst, ci->time, ci->mode, 0 /* no verify APK */)){ - return 1; - } - pushed++; - } else { - skipped++; - } - free(ci); - } - - fprintf(stderr,"%d file%s pushed. %d file%s skipped.\n", - pushed, (pushed == 1) ? "" : "s", - skipped, (skipped == 1) ? "" : "s"); - - return 0; -} - - -int do_sync_push(const char *lpath, const char *rpath, int verifyApk) -{ - struct stat st; - unsigned mode; - int fd; - - fd = adb_connect("sync:"); - if(fd < 0) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - if(stat(lpath, &st)) { - fprintf(stderr,"cannot stat '%s': %s\n", lpath, strerror(errno)); - sync_quit(fd); - return 1; - } - - if(S_ISDIR(st.st_mode)) { - BEGIN(); - if(copy_local_dir_remote(fd, lpath, rpath, 0)) { - return 1; - } else { - END(); - sync_quit(fd); - } - } else { - if(sync_readmode(fd, rpath, &mode)) { - return 1; - } - if((mode != 0) && S_ISDIR(mode)) { - /* if we're copying a local file to a remote directory, - ** we *really* want to copy to remotedir + "/" + localfilename - */ - const char *name = adb_dirstop(lpath); - if(name == 0) { - name = lpath; - } else { - name++; - } - int tmplen = strlen(name) + strlen(rpath) + 2; - char *tmp = malloc(strlen(name) + strlen(rpath) + 2); - if(tmp == 0) return 1; - snprintf(tmp, tmplen, "%s/%s", rpath, name); - rpath = tmp; - } - BEGIN(); - if(sync_send(fd, lpath, rpath, st.st_mtime, st.st_mode, verifyApk)) { - return 1; - } else { - END(); - sync_quit(fd); - return 0; - } - } - - return 0; -} - - -typedef struct { - copyinfo **filelist; - copyinfo **dirlist; - const char *rpath; - const char *lpath; -} sync_ls_build_list_cb_args; - -void -sync_ls_build_list_cb(unsigned mode, unsigned size, unsigned time, - const char *name, void *cookie) -{ - sync_ls_build_list_cb_args *args = (sync_ls_build_list_cb_args *)cookie; - copyinfo *ci; - - if (S_ISDIR(mode)) { - copyinfo **dirlist = args->dirlist; - - /* Don't try recursing down "." or ".." */ - if (name[0] == '.') { - if (name[1] == '\0') return; - if ((name[1] == '.') && (name[2] == '\0')) return; - } - - ci = mkcopyinfo(args->rpath, args->lpath, name, 1); - ci->next = *dirlist; - *dirlist = ci; - } else if (S_ISREG(mode) || S_ISLNK(mode)) { - copyinfo **filelist = args->filelist; - - ci = mkcopyinfo(args->rpath, args->lpath, name, 0); - ci->time = time; - ci->mode = mode; - ci->size = size; - ci->next = *filelist; - *filelist = ci; - } else { - fprintf(stderr, "skipping special file '%s'\n", name); - } -} - -static int remote_build_list(int syncfd, copyinfo **filelist, - const char *rpath, const char *lpath) -{ - copyinfo *dirlist = NULL; - sync_ls_build_list_cb_args args; - - args.filelist = filelist; - args.dirlist = &dirlist; - args.rpath = rpath; - args.lpath = lpath; - - /* Put the files/dirs in rpath on the lists. */ - if (sync_ls(syncfd, rpath, sync_ls_build_list_cb, (void *)&args)) { - return 1; - } - - /* Recurse into each directory we found. */ - while (dirlist != NULL) { - copyinfo *next = dirlist->next; - if (remote_build_list(syncfd, filelist, dirlist->src, dirlist->dst)) { - return 1; - } - free(dirlist); - dirlist = next; - } - - return 0; -} - -static int copy_remote_dir_local(int fd, const char *rpath, const char *lpath, - int checktimestamps) -{ - copyinfo *filelist = 0; - copyinfo *ci, *next; - int pulled = 0; - int skipped = 0; - - /* Make sure that both directory paths end in a slash. */ - if (rpath[0] == 0 || lpath[0] == 0) return -1; - if (rpath[strlen(rpath) - 1] != '/') { - int tmplen = strlen(rpath) + 2; - char *tmp = malloc(tmplen); - if (tmp == 0) return -1; - snprintf(tmp, tmplen, "%s/", rpath); - rpath = tmp; - } - if (lpath[strlen(lpath) - 1] != '/') { - int tmplen = strlen(lpath) + 2; - char *tmp = malloc(tmplen); - if (tmp == 0) return -1; - snprintf(tmp, tmplen, "%s/", lpath); - lpath = tmp; - } - - fprintf(stderr, "pull: building file list...\n"); - /* Recursively build the list of files to copy. */ - if (remote_build_list(fd, &filelist, rpath, lpath)) { - return -1; - } - -#if 0 - if (checktimestamps) { - for (ci = filelist; ci != 0; ci = ci->next) { - if (sync_start_readtime(fd, ci->dst)) { - return 1; - } - } - for (ci = filelist; ci != 0; ci = ci->next) { - unsigned int timestamp, mode, size; - if (sync_finish_readtime(fd, ×tamp, &mode, &size)) - return 1; - if (size == ci->size) { - /* for links, we cannot update the atime/mtime */ - if ((S_ISREG(ci->mode & mode) && timestamp == ci->time) || - (S_ISLNK(ci->mode & mode) && timestamp >= ci->time)) - ci->flag = 1; - } - } - } -#endif - for (ci = filelist; ci != 0; ci = next) { - next = ci->next; - if (ci->flag == 0) { - fprintf(stderr, "pull: %s -> %s\n", ci->src, ci->dst); - if (sync_recv(fd, ci->src, ci->dst)) { - return 1; - } - pulled++; - } else { - skipped++; - } - free(ci); - } - - fprintf(stderr, "%d file%s pulled. %d file%s skipped.\n", - pulled, (pulled == 1) ? "" : "s", - skipped, (skipped == 1) ? "" : "s"); - - return 0; -} - -int do_sync_pull(const char *rpath, const char *lpath) -{ - unsigned mode; - struct stat st; - - int fd; - - fd = adb_connect("sync:"); - if(fd < 0) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - if(sync_readmode(fd, rpath, &mode)) { - return 1; - } - if(mode == 0) { - fprintf(stderr,"remote object '%s' does not exist\n", rpath); - return 1; - } - - if(S_ISREG(mode) || S_ISCHR(mode) || S_ISBLK(mode)) { - if(stat(lpath, &st) == 0) { - if(S_ISDIR(st.st_mode)) { - /* if we're copying a remote file to a local directory, - ** we *really* want to copy to localdir + "/" + remotefilename - */ - const char *name = adb_dirstop(rpath); - if(name == 0) { - name = rpath; - } else { - name++; - } - int tmplen = strlen(name) + strlen(lpath) + 2; - char *tmp = malloc(tmplen); - if(tmp == 0) return 1; - snprintf(tmp, tmplen, "%s/%s", lpath, name); - lpath = tmp; - } - } - BEGIN(); - if(sync_recv(fd, rpath, lpath)) { - return 1; - } else { - END(); - sync_quit(fd); - return 0; - } - } else if(S_ISDIR(mode)) { - BEGIN(); - if (copy_remote_dir_local(fd, rpath, lpath, 0)) { - return 1; - } else { - END(); - sync_quit(fd); - return 0; - } - } else { - fprintf(stderr,"remote object '%s' not a file or directory\n", rpath); - return 1; - } -} - -int do_sync_sync(const char *lpath, const char *rpath) -{ - fprintf(stderr,"syncing %s...\n",rpath); - - int fd = adb_connect("sync:"); - if(fd < 0) { - fprintf(stderr,"error: %s\n", adb_error()); - return 1; - } - - BEGIN(); - if(copy_local_dir_remote(fd, lpath, rpath, 1)){ - return 1; - } else { - END(); - sync_quit(fd); - return 0; - } -} diff --git a/adb/file_sync_service.c b/adb/file_sync_service.c deleted file mode 100644 index a231e93d624d7d5ca3ab95cee1bf4ce6cf70b6fc..0000000000000000000000000000000000000000 --- a/adb/file_sync_service.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <utime.h> - -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_SYNC -#include "adb.h" -#include "file_sync_service.h" - -static int mkdirs(char *name) -{ - int ret; - char *x = name + 1; - - if(name[0] != '/') return -1; - - for(;;) { - x = adb_dirstart(x); - if(x == 0) return 0; - *x = 0; - ret = adb_mkdir(name, 0775); - if((ret < 0) && (errno != EEXIST)) { - D("mkdir(\"%s\") -> %s\n", name, strerror(errno)); - *x = '/'; - return ret; - } - *x++ = '/'; - } - return 0; -} - -static int do_stat(int s, const char *path) -{ - syncmsg msg; - struct stat st; - - msg.stat.id = ID_STAT; - - if(lstat(path, &st)) { - msg.stat.mode = 0; - msg.stat.size = 0; - msg.stat.time = 0; - } else { - msg.stat.mode = htoll(st.st_mode); - msg.stat.size = htoll(st.st_size); - msg.stat.time = htoll(st.st_mtime); - } - - return writex(s, &msg.stat, sizeof(msg.stat)); -} - -static int do_list(int s, const char *path) -{ - DIR *d; - struct dirent *de; - struct stat st; - syncmsg msg; - int len; - - char tmp[1024 + 256 + 1]; - char *fname; - - len = strlen(path); - memcpy(tmp, path, len); - tmp[len] = '/'; - fname = tmp + len + 1; - - msg.dent.id = ID_DENT; - - d = opendir(path); - if(d == 0) goto done; - - while((de = readdir(d))) { - int len = strlen(de->d_name); - - /* not supposed to be possible, but - if it does happen, let's not buffer overrun */ - if(len > 256) continue; - - strcpy(fname, de->d_name); - if(lstat(tmp, &st) == 0) { - msg.dent.mode = htoll(st.st_mode); - msg.dent.size = htoll(st.st_size); - msg.dent.time = htoll(st.st_mtime); - msg.dent.namelen = htoll(len); - - if(writex(s, &msg.dent, sizeof(msg.dent)) || - writex(s, de->d_name, len)) { - return -1; - } - } - } - - closedir(d); - -done: - msg.dent.id = ID_DONE; - msg.dent.mode = 0; - msg.dent.size = 0; - msg.dent.time = 0; - msg.dent.namelen = 0; - return writex(s, &msg.dent, sizeof(msg.dent)); -} - -static int fail_message(int s, const char *reason) -{ - syncmsg msg; - int len = strlen(reason); - - D("sync: failure: %s\n", reason); - - msg.data.id = ID_FAIL; - msg.data.size = htoll(len); - if(writex(s, &msg.data, sizeof(msg.data)) || - writex(s, reason, len)) { - return -1; - } else { - return 0; - } -} - -static int fail_errno(int s) -{ - return fail_message(s, strerror(errno)); -} - -static int handle_send_file(int s, char *path, mode_t mode, char *buffer) -{ - syncmsg msg; - unsigned int timestamp = 0; - int fd; - - fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); - if(fd < 0 && errno == ENOENT) { - mkdirs(path); - fd = adb_open_mode(path, O_WRONLY | O_CREAT | O_EXCL, mode); - } - if(fd < 0 && errno == EEXIST) { - fd = adb_open_mode(path, O_WRONLY, mode); - } - if(fd < 0) { - if(fail_errno(s)) - return -1; - fd = -1; - } - - for(;;) { - unsigned int len; - - if(readx(s, &msg.data, sizeof(msg.data))) - goto fail; - - if(msg.data.id != ID_DATA) { - if(msg.data.id == ID_DONE) { - timestamp = ltohl(msg.data.size); - break; - } - fail_message(s, "invalid data message"); - goto fail; - } - len = ltohl(msg.data.size); - if(len > SYNC_DATA_MAX) { - fail_message(s, "oversize data message"); - goto fail; - } - if(readx(s, buffer, len)) - goto fail; - - if(fd < 0) - continue; - if(writex(fd, buffer, len)) { - adb_close(fd); - adb_unlink(path); - fd = -1; - if(fail_errno(s)) return -1; - } - } - - if(fd >= 0) { - struct utimbuf u; - adb_close(fd); - u.actime = timestamp; - u.modtime = timestamp; - utime(path, &u); - - msg.status.id = ID_OKAY; - msg.status.msglen = 0; - if(writex(s, &msg.status, sizeof(msg.status))) - return -1; - } - return 0; - -fail: - if(fd >= 0) - adb_close(fd); - adb_unlink(path); - return -1; -} - -#ifdef HAVE_SYMLINKS -static int handle_send_link(int s, char *path, char *buffer) -{ - syncmsg msg; - unsigned int len; - int ret; - - if(readx(s, &msg.data, sizeof(msg.data))) - return -1; - - if(msg.data.id != ID_DATA) { - fail_message(s, "invalid data message: expected ID_DATA"); - return -1; - } - - len = ltohl(msg.data.size); - if(len > SYNC_DATA_MAX) { - fail_message(s, "oversize data message"); - return -1; - } - if(readx(s, buffer, len)) - return -1; - - ret = symlink(buffer, path); - if(ret && errno == ENOENT) { - mkdirs(path); - ret = symlink(buffer, path); - } - if(ret) { - fail_errno(s); - return -1; - } - - if(readx(s, &msg.data, sizeof(msg.data))) - return -1; - - if(msg.data.id == ID_DONE) { - msg.status.id = ID_OKAY; - msg.status.msglen = 0; - if(writex(s, &msg.status, sizeof(msg.status))) - return -1; - } else { - fail_message(s, "invalid data message: expected ID_DONE"); - return -1; - } - - return 0; -} -#endif /* HAVE_SYMLINKS */ - -static int do_send(int s, char *path, char *buffer) -{ - char *tmp; - mode_t mode; - int is_link, ret; - - tmp = strrchr(path,','); - if(tmp) { - *tmp = 0; - errno = 0; - mode = strtoul(tmp + 1, NULL, 0); -#ifndef HAVE_SYMLINKS - is_link = 0; -#else - is_link = S_ISLNK(mode); -#endif - mode &= 0777; - } - if(!tmp || errno) { - mode = 0644; - is_link = 0; - } - - adb_unlink(path); - - -#ifdef HAVE_SYMLINKS - if(is_link) - ret = handle_send_link(s, path, buffer); - else { -#else - { -#endif - /* copy user permission bits to "group" and "other" permissions */ - mode |= ((mode >> 3) & 0070); - mode |= ((mode >> 3) & 0007); - - ret = handle_send_file(s, path, mode, buffer); - } - - return ret; -} - -static int do_recv(int s, const char *path, char *buffer) -{ - syncmsg msg; - int fd, r; - - fd = adb_open(path, O_RDONLY); - if(fd < 0) { - if(fail_errno(s)) return -1; - return 0; - } - - msg.data.id = ID_DATA; - for(;;) { - r = adb_read(fd, buffer, SYNC_DATA_MAX); - if(r <= 0) { - if(r == 0) break; - if(errno == EINTR) continue; - r = fail_errno(s); - adb_close(fd); - return r; - } - msg.data.size = htoll(r); - if(writex(s, &msg.data, sizeof(msg.data)) || - writex(s, buffer, r)) { - adb_close(fd); - return -1; - } - } - - adb_close(fd); - - msg.data.id = ID_DONE; - msg.data.size = 0; - if(writex(s, &msg.data, sizeof(msg.data))) { - return -1; - } - - return 0; -} - -void file_sync_service(int fd, void *cookie) -{ - syncmsg msg; - char name[1025]; - unsigned namelen; - - char *buffer = malloc(SYNC_DATA_MAX); - if(buffer == 0) goto fail; - - for(;;) { - D("sync: waiting for command\n"); - - if(readx(fd, &msg.req, sizeof(msg.req))) { - fail_message(fd, "command read failure"); - break; - } - namelen = ltohl(msg.req.namelen); - if(namelen > 1024) { - fail_message(fd, "invalid namelen"); - break; - } - if(readx(fd, name, namelen)) { - fail_message(fd, "filename read failure"); - break; - } - name[namelen] = 0; - - msg.req.namelen = 0; - D("sync: '%s' '%s'\n", (char*) &msg.req, name); - - switch(msg.req.id) { - case ID_STAT: - if(do_stat(fd, name)) goto fail; - break; - case ID_LIST: - if(do_list(fd, name)) goto fail; - break; - case ID_SEND: - if(do_send(fd, name, buffer)) goto fail; - break; - case ID_RECV: - if(do_recv(fd, name, buffer)) goto fail; - break; - case ID_QUIT: - goto fail; - default: - fail_message(fd, "unknown command"); - goto fail; - } - } - -fail: - if(buffer != 0) free(buffer); - D("sync: done\n"); - adb_close(fd); -} diff --git a/adb/file_sync_service.h b/adb/file_sync_service.h deleted file mode 100644 index 4ee40ba24efb51eed64d754287b87d78af1a09a4..0000000000000000000000000000000000000000 --- a/adb/file_sync_service.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _FILE_SYNC_SERVICE_H_ -#define _FILE_SYNC_SERVICE_H_ - -#ifdef __ppc__ -static inline unsigned __swap_uint32(unsigned x) -{ - return (((x) & 0xFF000000) >> 24) - | (((x) & 0x00FF0000) >> 8) - | (((x) & 0x0000FF00) << 8) - | (((x) & 0x000000FF) << 24); -} -#define htoll(x) __swap_uint32(x) -#define ltohl(x) __swap_uint32(x) -#define MKID(a,b,c,d) ((d) | ((c) << 8) | ((b) << 16) | ((a) << 24)) -#else -#define htoll(x) (x) -#define ltohl(x) (x) -#define MKID(a,b,c,d) ((a) | ((b) << 8) | ((c) << 16) | ((d) << 24)) -#endif - -#define ID_STAT MKID('S','T','A','T') -#define ID_LIST MKID('L','I','S','T') -#define ID_ULNK MKID('U','L','N','K') -#define ID_SEND MKID('S','E','N','D') -#define ID_RECV MKID('R','E','C','V') -#define ID_DENT MKID('D','E','N','T') -#define ID_DONE MKID('D','O','N','E') -#define ID_DATA MKID('D','A','T','A') -#define ID_OKAY MKID('O','K','A','Y') -#define ID_FAIL MKID('F','A','I','L') -#define ID_QUIT MKID('Q','U','I','T') - -typedef union { - unsigned id; - struct { - unsigned id; - unsigned namelen; - } req; - struct { - unsigned id; - unsigned mode; - unsigned size; - unsigned time; - } stat; - struct { - unsigned id; - unsigned mode; - unsigned size; - unsigned time; - unsigned namelen; - } dent; - struct { - unsigned id; - unsigned size; - } data; - struct { - unsigned id; - unsigned msglen; - } status; -} syncmsg; - - -void file_sync_service(int fd, void *cookie); -int do_sync_ls(const char *path); -int do_sync_push(const char *lpath, const char *rpath, int verifyApk); -int do_sync_sync(const char *lpath, const char *rpath); -int do_sync_pull(const char *rpath, const char *lpath); - -#define SYNC_DATA_MAX (64*1024) - -#endif diff --git a/adb/framebuffer_service.c b/adb/framebuffer_service.c deleted file mode 100644 index 0de0dd5e687fce7df8c53453b6ca2b2546d43817..0000000000000000000000000000000000000000 --- a/adb/framebuffer_service.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> - -#include <cutils/fdevent.h> -#include "adb.h" - -#include <linux/fb.h> -#include <sys/ioctl.h> -#include <sys/mman.h> - -/* TODO: -** - grab the current buffer, not the first buffer -** - sync with vsync to avoid tearing -*/ - -void framebuffer_service(int fd, void *cookie) -{ - struct fb_var_screeninfo vinfo; - int fb; - void *ptr = MAP_FAILED; - char x; - - unsigned fbinfo[4]; - - fb = open("/dev/graphics/fb0", O_RDONLY); - if(fb < 0) goto done; - - if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done; - fcntl(fb, F_SETFD, FD_CLOEXEC); - - fbinfo[0] = 16; - fbinfo[1] = vinfo.xres * vinfo.yres * 2; - fbinfo[2] = vinfo.xres; - fbinfo[3] = vinfo.yres; - - ptr = mmap(0, fbinfo[1], PROT_READ, MAP_SHARED, fb, 0); - if(ptr == MAP_FAILED) goto done; - - if(writex(fd, fbinfo, sizeof(unsigned) * 4)) goto done; - - for(;;) { - if(readx(fd, &x, 1)) goto done; - if(writex(fd, ptr, fbinfo[1])) goto done; - } - -done: - if(ptr != MAP_FAILED) munmap(ptr, fbinfo[1]); - if(fb >= 0) close(fb); - close(fd); -} - diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c deleted file mode 100644 index 00dfee433e10a5308721f8ff73f35f7ae51838bc..0000000000000000000000000000000000000000 --- a/adb/get_my_path_darwin.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <utils/executablepath.h> -#import <Carbon/Carbon.h> -#include <unistd.h> - -void get_my_path(char s[PATH_MAX]) -{ - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - CFDictionaryRef dict; - dict = ProcessInformationCopyDictionary(&psn, 0xffffffff); - CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, - CFSTR("CFBundleExecutable")); - CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8); -} - diff --git a/adb/get_my_path_linux.c b/adb/get_my_path_linux.c deleted file mode 100644 index f516e591d2ac2ea7172f41c83a2f853d650b616f..0000000000000000000000000000000000000000 --- a/adb/get_my_path_linux.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sys/types.h> -#include <unistd.h> -#include <limits.h> -#include <stdio.h> - -void get_my_path(char exe[PATH_MAX]) -{ - char proc[64]; - snprintf(proc, sizeof proc, "/proc/%d/exe", getpid()); - int err = readlink(proc, exe, PATH_MAX - 1); - if(err > 0) { - exe[err] = 0; - } else { - exe[0] = 0; - } -} - diff --git a/adb/get_my_path_windows.c b/adb/get_my_path_windows.c deleted file mode 100644 index fc7143c107b03de026734d652ba8ca86e91a570b..0000000000000000000000000000000000000000 --- a/adb/get_my_path_windows.c +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <limits.h> -#include <assert.h> -#include <windows.h> - -void get_my_path(char exe[PATH_MAX]) -{ - char* r; - - GetModuleFileName( NULL, exe, PATH_MAX-1 ); - exe[PATH_MAX-1] = 0; - r = strrchr( exe, '\\' ); - if (r) - *r = 0; -} - diff --git a/adb/history.h b/adb/history.h deleted file mode 100755 index ef86ad9b1d096baf7aed0851a62d2374be9dcbfb..0000000000000000000000000000000000000000 --- a/adb/history.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _HISTORY_H_ -#define _HISTORY_H_ - -#define SH_ARROW_ANY "\x1b\x5b" -#define SH_ARROW_UP '\x41' -#define SH_ARROW_DOWN '\x42' -#define SH_ARROW_RIGHT '\x43' -#define SH_ARROW_LEFT '\x44' -#define SH_DEL_CHAR '\x7F' -#define SH_BLANK_CHAR '\x20' - -#endif - diff --git a/adb/jdwp_service.c b/adb/jdwp_service.c deleted file mode 100644 index ae7f12dfd14547f8d06833b2bf0edb4690234bb5..0000000000000000000000000000000000000000 --- a/adb/jdwp_service.c +++ /dev/null @@ -1,709 +0,0 @@ -/* implement the "debug-ports" and "track-debug-ports" device services */ -#include "sysdeps.h" -#define TRACE_TAG TRACE_JDWP -#include "adb.h" -#include <errno.h> -#include <stdio.h> -#include <string.h> - -/* here's how these things work. - - when adbd starts, it creates a unix server socket - named @vm-debug-control (@ is a shortcut for "first byte is zero" - to use the private namespace instead of the file system) - - when a new JDWP daemon thread starts in a new VM process, it creates - a connection to @vm-debug-control to announce its availability. - - - JDWP thread @vm-debug-control - | | - |-------------------------------> | - | hello I'm in process <pid> | - | | - | | - - the connection is kept alive. it will be closed automatically if - the JDWP process terminates (this allows adbd to detect dead - processes). - - adbd thus maintains a list of "active" JDWP processes. it can send - its content to clients through the "device:debug-ports" service, - or even updates through the "device:track-debug-ports" service. - - when a debugger wants to connect, it simply runs the command - equivalent to "adb forward tcp:<hostport> jdwp:<pid>" - - "jdwp:<pid>" is a new forward destination format used to target - a given JDWP process on the device. when sutch a request arrives, - adbd does the following: - - - first, it calls socketpair() to create a pair of equivalent - sockets. - - - it attaches the first socket in the pair to a local socket - which is itself attached to the transport's remote socket: - - - - it sends the file descriptor of the second socket directly - to the JDWP process with the help of sendmsg() - - - JDWP thread @vm-debug-control - | | - | <----------------------| - | OK, try this file descriptor | - | | - | | - - then, the JDWP thread uses this new socket descriptor as its - pass-through connection to the debugger (and receives the - JDWP-Handshake message, answers to it, etc...) - - this gives the following graphics: - ____________________________________ - | | - | ADB Server (host) | - | | - Debugger <---> LocalSocket <----> RemoteSocket | - | ^^ | - |___________________________||_______| - || - Transport || - (TCP for emulator - USB for device) || - || - ___________________________||_______ - | || | - | ADBD (device) || | - | VV | - JDWP <======> LocalSocket <----> RemoteSocket | - | | - |____________________________________| - - due to the way adb works, this doesn't need a special socket - type or fancy handling of socket termination if either the debugger - or the JDWP process closes the connection. - - THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN - TO HAVE A BETTER IDEA, LET ME KNOW - Digit - -**********************************************************************/ - -/** JDWP PID List Support Code - ** for each JDWP process, we record its pid and its connected socket - **/ - -#define MAX_OUT_FDS 4 - -#if !ADB_HOST - -#include <sys/socket.h> -#include <sys/un.h> - -typedef struct JdwpProcess JdwpProcess; -struct JdwpProcess { - JdwpProcess* next; - JdwpProcess* prev; - int pid; - int socket; - fdevent* fde; - - char in_buff[4]; /* input character to read PID */ - int in_len; /* number from JDWP process */ - - int out_fds[MAX_OUT_FDS]; /* output array of file descriptors */ - int out_count; /* to send to the JDWP process */ -}; - -static JdwpProcess _jdwp_list; - -static int -jdwp_process_list( char* buffer, int bufferlen ) -{ - char* end = buffer + bufferlen; - char* p = buffer; - JdwpProcess* proc = _jdwp_list.next; - - for ( ; proc != &_jdwp_list; proc = proc->next ) { - int len; - - /* skip transient connections */ - if (proc->pid < 0) - continue; - - len = snprintf(p, end-p, "%d\n", proc->pid); - if (p + len >= end) - break; - p += len; - } - p[0] = 0; - return (p - buffer); -} - - -static int -jdwp_process_list_msg( char* buffer, int bufferlen ) -{ - char head[5]; - int len = jdwp_process_list( buffer+4, bufferlen-4 ); - snprintf(head, sizeof head, "%04x", len); - memcpy(buffer, head, 4); - return len + 4; -} - - -static void jdwp_process_list_updated(void); - -static void -jdwp_process_free( JdwpProcess* proc ) -{ - if (proc) { - int n; - - proc->prev->next = proc->next; - proc->next->prev = proc->prev; - - if (proc->socket >= 0) { - shutdown(proc->socket, SHUT_RDWR); - adb_close(proc->socket); - proc->socket = -1; - } - - if (proc->fde != NULL) { - fdevent_destroy(proc->fde); - proc->fde = NULL; - } - proc->pid = -1; - - for (n = 0; n < proc->out_count; n++) { - adb_close(proc->out_fds[n]); - } - proc->out_count = 0; - - free(proc); - - jdwp_process_list_updated(); - } -} - - -static void jdwp_process_event(int, unsigned, void*); /* forward */ - - -static JdwpProcess* -jdwp_process_alloc( int socket ) -{ - JdwpProcess* proc = calloc(1,sizeof(*proc)); - - if (proc == NULL) { - D("not enough memory to create new JDWP process\n"); - return NULL; - } - - proc->socket = socket; - proc->pid = -1; - proc->next = proc; - proc->prev = proc; - - proc->fde = fdevent_create( socket, jdwp_process_event, proc ); - if (proc->fde == NULL) { - D("could not create fdevent for new JDWP process\n" ); - free(proc); - return NULL; - } - - proc->fde->state |= FDE_DONT_CLOSE; - proc->in_len = 0; - proc->out_count = 0; - - /* append to list */ - proc->next = &_jdwp_list; - proc->prev = proc->next->prev; - - proc->prev->next = proc; - proc->next->prev = proc; - - /* start by waiting for the PID */ - fdevent_add(proc->fde, FDE_READ); - - return proc; -} - - -static void -jdwp_process_event( int socket, unsigned events, void* _proc ) -{ - JdwpProcess* proc = _proc; - - if (events & FDE_READ) { - if (proc->pid < 0) { - /* read the PID as a 4-hexchar string */ - char* p = proc->in_buff + proc->in_len; - int size = 4 - proc->in_len; - char temp[5]; - while (size > 0) { - int len = recv( socket, p, size, 0 ); - if (len < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - return; - /* this can fail here if the JDWP process crashes very fast */ - D("weird unknown JDWP process failure: %s\n", - strerror(errno)); - - goto CloseProcess; - } - if (len == 0) { /* end of stream ? */ - D("weird end-of-stream from unknown JDWP process\n"); - goto CloseProcess; - } - p += len; - proc->in_len += len; - size -= len; - } - /* we have read 4 characters, now decode the pid */ - memcpy(temp, proc->in_buff, 4); - temp[4] = 0; - - if (sscanf( temp, "%04x", &proc->pid ) != 1) { - D("could not decode JDWP %p PID number: '%s'\n", proc, temp); - goto CloseProcess; - } - - /* all is well, keep reading to detect connection closure */ - D("Adding pid %d to jdwp process list\n", proc->pid); - jdwp_process_list_updated(); - } - else - { - /* the pid was read, if we get there it's probably because the connection - * was closed (e.g. the JDWP process exited or crashed) */ - char buf[32]; - - for (;;) { - int len = recv(socket, buf, sizeof(buf), 0); - - if (len <= 0) { - if (len < 0 && errno == EINTR) - continue; - if (len < 0 && errno == EAGAIN) - return; - else { - D("terminating JDWP %d connection: %s\n", proc->pid, - strerror(errno)); - break; - } - } - else { - D( "ignoring unexpected JDWP %d control socket activity (%d bytes)\n", - proc->pid, len ); - } - } - - CloseProcess: - if (proc->pid >= 0) - D( "remove pid %d to jdwp process list\n", proc->pid ); - jdwp_process_free(proc); - return; - } - } - - if (events & FDE_WRITE) { - D("trying to write to JDWP pid controli (count=%d first=%d) %d\n", - proc->pid, proc->out_count, proc->out_fds[0]); - if (proc->out_count > 0) { - int fd = proc->out_fds[0]; - int n, ret; - struct cmsghdr* cmsg; - struct msghdr msg; - struct iovec iov; - char dummy = '!'; - char buffer[sizeof(struct cmsghdr) + sizeof(int)]; - - iov.iov_base = &dummy; - iov.iov_len = 1; - msg.msg_name = NULL; - msg.msg_namelen = 0; - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_flags = 0; - msg.msg_control = buffer; - msg.msg_controllen = sizeof(buffer); - - cmsg = CMSG_FIRSTHDR(&msg); - cmsg->cmsg_len = msg.msg_controllen; - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - ((int*)CMSG_DATA(cmsg))[0] = fd; - - for (;;) { - ret = sendmsg(proc->socket, &msg, 0); - if (ret >= 0) - break; - if (errno == EINTR) - continue; - D("sending new file descriptor to JDWP %d failed: %s\n", - proc->pid, strerror(errno)); - goto CloseProcess; - } - - D("sent file descriptor %d to JDWP process %d\n", - fd, proc->pid); - - for (n = 1; n < proc->out_count; n++) - proc->out_fds[n-1] = proc->out_fds[n]; - - if (--proc->out_count == 0) - fdevent_del( proc->fde, FDE_WRITE ); - } - } -} - - -int -create_jdwp_connection_fd(int pid) -{ - JdwpProcess* proc = _jdwp_list.next; - - D("looking for pid %d in JDWP process list\n", pid); - for ( ; proc != &_jdwp_list; proc = proc->next ) { - if (proc->pid == pid) { - goto FoundIt; - } - } - D("search failed !!\n"); - return -1; - -FoundIt: - { - int fds[2]; - - if (proc->out_count >= MAX_OUT_FDS) { - D("%s: too many pending JDWP connection for pid %d\n", - __FUNCTION__, pid); - return -1; - } - - if (adb_socketpair(fds) < 0) { - D("%s: socket pair creation failed: %s\n", - __FUNCTION__, strerror(errno)); - return -1; - } - - proc->out_fds[ proc->out_count ] = fds[1]; - if (++proc->out_count == 1) - fdevent_add( proc->fde, FDE_WRITE ); - - return fds[0]; - } -} - -/** VM DEBUG CONTROL SOCKET - ** - ** we do implement a custom asocket to receive the data - **/ - -/* name of the debug control Unix socket */ -#define JDWP_CONTROL_NAME "\0jdwp-control" -#define JDWP_CONTROL_NAME_LEN (sizeof(JDWP_CONTROL_NAME)-1) - -typedef struct { - int listen_socket; - fdevent* fde; - -} JdwpControl; - - -static void -jdwp_control_event(int s, unsigned events, void* user); - - -static int -jdwp_control_init( JdwpControl* control, - const char* sockname, - int socknamelen ) -{ - struct sockaddr_un addr; - socklen_t addrlen; - int s; - int maxpath = sizeof(addr.sun_path); - int pathlen = socknamelen; - - if (pathlen >= maxpath) { - D( "vm debug control socket name too long (%d extra chars)\n", - pathlen+1-maxpath ); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_UNIX; - memcpy(addr.sun_path, sockname, socknamelen); - - s = socket( AF_UNIX, SOCK_STREAM, 0 ); - if (s < 0) { - D( "could not create vm debug control socket. %d: %s\n", - errno, strerror(errno)); - return -1; - } - - addrlen = (pathlen + sizeof(addr.sun_family)); - - if (bind(s, (struct sockaddr*)&addr, addrlen) < 0) { - D( "could not bind vm debug control socket: %d: %s\n", - errno, strerror(errno) ); - adb_close(s); - return -1; - } - - if ( listen(s, 4) < 0 ) { - D("listen failed in jdwp control socket: %d: %s\n", - errno, strerror(errno)); - adb_close(s); - return -1; - } - - control->listen_socket = s; - - control->fde = fdevent_create(s, jdwp_control_event, control); - if (control->fde == NULL) { - D( "could not create fdevent for jdwp control socket\n" ); - adb_close(s); - return -1; - } - - /* only wait for incoming connections */ - fdevent_add(control->fde, FDE_READ); - - D("jdwp control socket started (%d)\n", control->listen_socket); - return 0; -} - - -static void -jdwp_control_event( int s, unsigned events, void* _control ) -{ - JdwpControl* control = (JdwpControl*) _control; - - if (events & FDE_READ) { - struct sockaddr addr; - socklen_t addrlen = sizeof(addr); - int s = -1; - JdwpProcess* proc; - - do { - s = adb_socket_accept( control->listen_socket, &addr, &addrlen ); - if (s < 0) { - if (errno == EINTR) - continue; - if (errno == ECONNABORTED) { - /* oops, the JDWP process died really quick */ - D("oops, the JDWP process died really quick\n"); - return; - } - /* the socket is probably closed ? */ - D( "weird accept() failed on jdwp control socket: %s\n", - strerror(errno) ); - return; - } - } - while (s < 0); - - proc = jdwp_process_alloc( s ); - if (proc == NULL) - return; - } -} - - -static JdwpControl _jdwp_control; - -/** "jdwp" local service implementation - ** this simply returns the list of known JDWP process pids - **/ - -typedef struct { - asocket socket; - int pass; -} JdwpSocket; - -static void -jdwp_socket_close( asocket* s ) -{ - asocket* peer = s->peer; - - remove_socket(s); - - if (peer) { - peer->peer = NULL; - peer->close(peer); - } - free(s); -} - -static int -jdwp_socket_enqueue( asocket* s, apacket* p ) -{ - /* you can't write to this asocket */ - put_apacket(p); - s->peer->close(s->peer); - return -1; -} - - -static void -jdwp_socket_ready( asocket* s ) -{ - JdwpSocket* jdwp = (JdwpSocket*)s; - asocket* peer = jdwp->socket.peer; - - /* on the first call, send the list of pids, - * on the second one, close the connection - */ - if (jdwp->pass == 0) { - apacket* p = get_apacket(); - p->len = jdwp_process_list((char*)p->data, MAX_PAYLOAD); - peer->enqueue(peer, p); - jdwp->pass = 1; - } - else { - peer->close(peer); - } -} - -asocket* -create_jdwp_service_socket( void ) -{ - JdwpSocket* s = calloc(sizeof(*s),1); - - if (s == NULL) - return NULL; - - install_local_socket(&s->socket); - - s->socket.ready = jdwp_socket_ready; - s->socket.enqueue = jdwp_socket_enqueue; - s->socket.close = jdwp_socket_close; - s->pass = 0; - - return &s->socket; -} - -/** "track-jdwp" local service implementation - ** this periodically sends the list of known JDWP process pids - ** to the client... - **/ - -typedef struct JdwpTracker JdwpTracker; - -struct JdwpTracker { - asocket socket; - JdwpTracker* next; - JdwpTracker* prev; - int need_update; -}; - -static JdwpTracker _jdwp_trackers_list; - - -static void -jdwp_process_list_updated(void) -{ - char buffer[1024]; - int len; - JdwpTracker* t = _jdwp_trackers_list.next; - - len = jdwp_process_list_msg(buffer, sizeof(buffer)); - - for ( ; t != &_jdwp_trackers_list; t = t->next ) { - apacket* p = get_apacket(); - asocket* peer = t->socket.peer; - memcpy(p->data, buffer, len); - p->len = len; - peer->enqueue( peer, p ); - } -} - -static void -jdwp_tracker_close( asocket* s ) -{ - JdwpTracker* tracker = (JdwpTracker*) s; - asocket* peer = s->peer; - - if (peer) { - peer->peer = NULL; - peer->close(peer); - } - - remove_socket(s); - - tracker->prev->next = tracker->next; - tracker->next->prev = tracker->prev; - - free(s); -} - -static void -jdwp_tracker_ready( asocket* s ) -{ - JdwpTracker* t = (JdwpTracker*) s; - - if (t->need_update) { - apacket* p = get_apacket(); - t->need_update = 0; - p->len = jdwp_process_list_msg((char*)p->data, sizeof(p->data)); - s->peer->enqueue(s->peer, p); - } -} - -static int -jdwp_tracker_enqueue( asocket* s, apacket* p ) -{ - /* you can't write to this socket */ - put_apacket(p); - s->peer->close(s->peer); - return -1; -} - - -asocket* -create_jdwp_tracker_service_socket( void ) -{ - JdwpTracker* t = calloc(sizeof(*t),1); - - if (t == NULL) - return NULL; - - t->next = &_jdwp_trackers_list; - t->prev = t->next->prev; - - t->next->prev = t; - t->prev->next = t; - - install_local_socket(&t->socket); - - t->socket.ready = jdwp_tracker_ready; - t->socket.enqueue = jdwp_tracker_enqueue; - t->socket.close = jdwp_tracker_close; - t->need_update = 1; - - return &t->socket; -} - - -int -init_jdwp(void) -{ - _jdwp_list.next = &_jdwp_list; - _jdwp_list.prev = &_jdwp_list; - - _jdwp_trackers_list.next = &_jdwp_trackers_list; - _jdwp_trackers_list.prev = &_jdwp_trackers_list; - - return jdwp_control_init( &_jdwp_control, - JDWP_CONTROL_NAME, - JDWP_CONTROL_NAME_LEN ); -} - -#endif /* !ADB_HOST */ - diff --git a/adb/log_service.c b/adb/log_service.c deleted file mode 100644 index 6e9bdeee650c32798c36b0d1f6c9270dccfaef0f..0000000000000000000000000000000000000000 --- a/adb/log_service.c +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <sys/socket.h> -#include <cutils/logger.h> -#include "sysdeps.h" -#include "adb.h" - -#define LOG_FILE_DIR "/dev/log/" - -void write_log_entry(int fd, struct logger_entry *buf); - -void log_service(int fd, void *cookie) -{ - /* get the name of the log filepath to read */ - char * log_filepath = cookie; - - /* open the log file. */ - int logfd = unix_open(log_filepath, O_RDONLY); - if (logfd < 0) { - goto done; - } - - // temp buffer to read the entries - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); - struct logger_entry *entry = (struct logger_entry *) buf; - - while (1) { - int ret; - - ret = unix_read(logfd, entry, LOGGER_ENTRY_MAX_LEN); - if (ret < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - // perror("logcat read"); - goto done; - } - else if (!ret) { - // fprintf(stderr, "read: Unexpected EOF!\n"); - goto done; - } - - /* NOTE: driver guarantees we read exactly one full entry */ - - entry->msg[entry->len] = '\0'; - - write_log_entry(fd, entry); - } - -done: - unix_close(fd); - free(log_filepath); -} - -/* returns the full path to the log file in a newly allocated string */ -char * get_log_file_path(const char * log_name) { - char *log_device = malloc(strlen(LOG_FILE_DIR) + strlen(log_name) + 1); - - strcpy(log_device, LOG_FILE_DIR); - strcat(log_device, log_name); - - return log_device; -} - - -/* prints one log entry into the file descriptor fd */ -void write_log_entry(int fd, struct logger_entry *buf) -{ - size_t size = sizeof(struct logger_entry) + buf->len; - - writex(fd, buf, size); -} diff --git a/adb/mutex_list.h b/adb/mutex_list.h deleted file mode 100644 index eebe0dfcbbd451a984e81a7ff38f9c40a812885e..0000000000000000000000000000000000000000 --- a/adb/mutex_list.h +++ /dev/null @@ -1,14 +0,0 @@ -/* the list of mutexes used by addb */ -#ifndef ADB_MUTEX -#error ADB_MUTEX not defined when including this file -#endif - -ADB_MUTEX(dns_lock) -ADB_MUTEX(socket_list_lock) -ADB_MUTEX(transport_lock) -#if ADB_HOST -ADB_MUTEX(local_transports_lock) -#endif -ADB_MUTEX(usb_lock) - -#undef ADB_MUTEX diff --git a/adb/protocol.txt b/adb/protocol.txt deleted file mode 100644 index d0f307cfe0e3d4f4faabf86fa4cb278effcfa304..0000000000000000000000000000000000000000 --- a/adb/protocol.txt +++ /dev/null @@ -1,252 +0,0 @@ - ---- a replacement for aproto ------------------------------------------- - -When it comes down to it, aproto's primary purpose is to forward -various streams between the host computer and client device (in either -direction). - -This replacement further simplifies the concept, reducing the protocol -to an extremely straightforward model optimized to accomplish the -forwarding of these streams and removing additional state or -complexity. - -The host side becomes a simple comms bridge with no "UI", which will -be used by either commandline or interactive tools to communicate with -a device or emulator that is connected to the bridge. - -The protocol is designed to be straightforward and well-defined enough -that if it needs to be reimplemented in another environment (Java -perhaps), there should not problems ensuring perfect interoperability. - -The protocol discards the layering aproto has and should allow the -implementation to be much more robust. - - ---- protocol overview and basics --------------------------------------- - -The transport layer deals in "messages", which consist of a 24 byte -header followed (optionally) by a payload. The header consists of 6 -32 bit words which are sent across the wire in little endian format. - -struct message { - unsigned command; /* command identifier constant */ - unsigned arg0; /* first argument */ - unsigned arg1; /* second argument */ - unsigned data_length; /* length of payload (0 is allowed) */ - unsigned data_crc32; /* crc32 of data payload */ - unsigned magic; /* command ^ 0xffffffff */ -}; - -Receipt of an invalid message header, corrupt message payload, or an -unrecognized command MUST result in the closing of the remote -connection. The protocol depends on shared state and any break in the -message stream will result in state getting out of sync. - -The following sections describe the six defined message types in -detail. Their format is COMMAND(arg0, arg1, payload) where the payload -is represented by a quoted string or an empty string if none should be -sent. - -The identifiers "local-id" and "remote-id" are always relative to the -*sender* of the message, so for a receiver, the meanings are effectively -reversed. - - - ---- CONNECT(version, maxdata, "system-identity-string") ---------------- - -The CONNECT message establishes the presence of a remote system. -The version is used to ensure protocol compatibility and maxdata -declares the maximum message body size that the remote system -is willing to accept. - -Currently, version=0x01000000 and maxdata=4096 - -Both sides send a CONNECT message when the connection between them is -established. Until a CONNECT message is received no other messages may -be sent. Any messages received before a CONNECT message MUST be ignored. - -If a CONNECT message is received with an unknown version or insufficiently -large maxdata value, the connection with the other side must be closed. - -The system identity string should be "<systemtype>:<serialno>:<banner>" -where systemtype is "bootloader", "device", or "host", serialno is some -kind of unique ID (or empty), and banner is a human-readable version -or identifier string (informational only). - - ---- OPEN(local-id, 0, "destination") ----------------------------------- - -The OPEN message informs the recipient that the sender has a stream -identified by local-id that it wishes to connect to the named -destination in the message payload. The local-id may not be zero. - -The OPEN message MUST result in either a READY message indicating that -the connection has been established (and identifying the other end) or -a CLOSE message, indicating failure. An OPEN message also implies -a READY message sent at the same time. - -Common destination naming conventions include: - -* "tcp:<host>:<port>" - host may be omitted to indicate localhost -* "udp:<host>:<port>" - host may be omitted to indicate localhost -* "local-dgram:<identifier>" -* "local-stream:<identifier>" -* "shell" - local shell service -* "upload" - service for pushing files across (like aproto's /sync) -* "fs-bridge" - FUSE protocol filesystem bridge - - ---- READY(local-id, remote-id, "") ------------------------------------- - -The READY message informs the recipient that the sender's stream -identified by local-id is ready for write messages and that it is -connected to the recipient's stream identified by remote-id. - -Neither the local-id nor the remote-id may be zero. - -A READY message containing a remote-id which does not map to an open -stream on the recipient's side is ignored. The stream may have been -closed while this message was in-flight. - -The local-id is ignored on all but the first READY message (where it -is used to establish the connection). Nonetheless, the local-id MUST -not change on later READY messages sent to the same stream. - - - ---- WRITE(0, remote-id, "data") ---------------------------------------- - -The WRITE message sends data to the recipient's stream identified by -remote-id. The payload MUST be <= maxdata in length. - -A WRITE message containing a remote-id which does not map to an open -stream on the recipient's side is ignored. The stream may have been -closed while this message was in-flight. - -A WRITE message may not be sent until a READY message is received. -Once a WRITE message is sent, an additional WRITE message may not be -sent until another READY message has been received. Recipients of -a WRITE message that is in violation of this requirement will CLOSE -the connection. - - ---- CLOSE(local-id, remote-id, "") ------------------------------------- - -The CLOSE message informs recipient that the connection between the -sender's stream (local-id) and the recipient's stream (remote-id) is -broken. The remote-id MUST not be zero, but the local-id MAY be zero -if this CLOSE indicates a failed OPEN. - -A CLOSE message containing a remote-id which does not map to an open -stream on the recipient's side is ignored. The stream may have -already been closed by the recipient while this message was in-flight. - -The recipient should not respond to a CLOSE message in any way. The -recipient should cancel pending WRITEs or CLOSEs, but this is not a -requirement, since they will be ignored. - - ---- SYNC(online, sequence, "") ----------------------------------------- - -The SYNC message is used by the io pump to make sure that stale -outbound messages are discarded when the connection to the remote side -is broken. It is only used internally to the bridge and never valid -to send across the wire. - -* when the connection to the remote side goes offline, the io pump - sends a SYNC(0, 0) and starts discarding all messages -* when the connection to the remote side is established, the io pump - sends a SYNC(1, token) and continues to discard messages -* when the io pump receives a matching SYNC(1, token), it once again - starts accepting messages to forward to the remote side - - ---- message command constants ------------------------------------------ - -#define A_SYNC 0x434e5953 -#define A_CNXN 0x4e584e43 -#define A_OPEN 0x4e45504f -#define A_OKAY 0x59414b4f -#define A_CLSE 0x45534c43 -#define A_WRTE 0x45545257 - - - ---- implementation details --------------------------------------------- - -The core of the bridge program will use three threads. One thread -will be a select/epoll loop to handle io between various inbound and -outbound connections and the connection to the remote side. - -The remote side connection will be implemented as two threads (one for -reading, one for writing) and a datagram socketpair to provide the -channel between the main select/epoll thread and the remote connection -threadpair. The reason for this is that for usb connections, the -kernel interface on linux and osx does not allow you to do meaningful -nonblocking IO. - -The endian swapping for the message headers will happen (as needed) in -the remote connection threadpair and that the rest of the program will -always treat message header values as native-endian. - -The bridge program will be able to have a number of mini-servers -compiled in. They will be published under known names (examples -"shell", "fs-bridge", etc) and upon receiving an OPEN() to such a -service, the bridge program will create a stream socketpair and spawn -a thread or subprocess to handle the io. - - ---- simplified / embedded implementation ------------------------------- - -For limited environments, like the bootloader, it is allowable to -support a smaller, fixed number of channels using pre-assigned channel -ID numbers such that only one stream may be connected to a bootloader -endpoint at any given time. The protocol remains unchanged, but the -"embedded" version of it is less dynamic. - -The bootloader will support two streams. A "bootloader:debug" stream, -which may be opened to get debug messages from the bootloader and a -"bootloader:control", stream which will support the set of basic -bootloader commands. - -Example command stream dialogues: - "flash_kernel,2515049,........\n" "okay\n" - "flash_ramdisk,5038,........\n" "fail,flash write error\n" - "bogus_command......" <CLOSE> - - ---- future expansion --------------------------------------------------- - -I plan on providing either a message or a special control stream so that -the client device could ask the host computer to setup inbound socket -translations on the fly on behalf of the client device. - - -The initial design does handshaking to provide flow control, with a -message flow that looks like: - - >OPEN <READY >WRITE <READY >WRITE <READY >WRITE <CLOSE - -The far side may choose to issue the READY message as soon as it receives -a WRITE or it may defer the READY until the write to the local stream -succeeds. A future version may want to do some level of windowing where -multiple WRITEs may be sent without requiring individual READY acks. - ------------------------------------------------------------------------- - ---- smartsockets ------------------------------------------------------- - -Port 5037 is used for smart sockets which allow a client on the host -side to request access to a service in the host adb daemon or in the -remote (device) daemon. The service is requested by ascii name, -preceeded by a 4 digit hex length. Upon successful connection an -"OKAY" response is sent, otherwise a "FAIL" message is returned. Once -connected the client is talking to that (remote or local) service. - -client: <hex4> <service-name> -server: "OKAY" - -client: <hex4> <service-name> -server: "FAIL" <hex4> <reason> - diff --git a/adb/remount_service.c b/adb/remount_service.c deleted file mode 100644 index 26bc841c9426ab632e0b61ec38e099557c171edb..0000000000000000000000000000000000000000 --- a/adb/remount_service.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <sys/mount.h> -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_ADB -#include "adb.h" - - -static int system_ro = 1; - -/* Returns the mount number of the requested partition from /proc/mtd */ -static int find_mount(const char *findme) -{ - int fd; - int res; - int size; - char *token = NULL; - const char delims[] = "\n"; - char buf[1024]; - - fd = unix_open("/proc/mtd", O_RDONLY); - if (fd < 0) - return -errno; - - buf[sizeof(buf) - 1] = '\0'; - size = adb_read(fd, buf, sizeof(buf) - 1); - adb_close(fd); - - token = strtok(buf, delims); - - while (token) { - char mtdname[16]; - int mtdnum, mtdsize, mtderasesize; - - res = sscanf(token, "mtd%d: %x %x %15s", - &mtdnum, &mtdsize, &mtderasesize, mtdname); - - if (res == 4 && !strcmp(mtdname, findme)) - return mtdnum; - - token = strtok(NULL, delims); - } - return -1; -} - -/* Init mounts /system as read only, remount to enable writes. */ -static int remount_system() -{ - int num; - char source[64]; - if (system_ro == 0) { - return 0; - } - if ((num = find_mount("\"system\"")) < 0) - return -1; - - snprintf(source, sizeof source, "/dev/block/mtdblock%d", num); - system_ro = mount(source, "/system", "yaffs2", MS_REMOUNT, NULL); - return system_ro; -} - -static void write_string(int fd, const char* str) -{ - writex(fd, str, strlen(str)); -} - -void remount_service(int fd, void *cookie) -{ - int ret = remount_system(); - - if (!ret) - write_string(fd, "remount succeeded\n"); - else { - char buffer[200]; - snprintf(buffer, sizeof(buffer), "remount failed: %s\n", strerror(errno)); - write_string(fd, buffer); - } - - adb_close(fd); -} - diff --git a/adb/services.c b/adb/services.c deleted file mode 100644 index e686949c9c8cdff1c4ef6f751d75d9d5ce1a6628..0000000000000000000000000000000000000000 --- a/adb/services.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_ADB -#include "adb.h" -#include "file_sync_service.h" - -#if ADB_HOST -# ifndef HAVE_WINSOCK -# include <netinet/in.h> -# include <netdb.h> -# endif -#endif - -typedef struct stinfo stinfo; - -struct stinfo { - void (*func)(int fd, void *cookie); - int fd; - void *cookie; -}; - - -void *service_bootstrap_func(void *x) -{ - stinfo *sti = x; - sti->func(sti->fd, sti->cookie); - free(sti); - return 0; -} - -#if ADB_HOST -ADB_MUTEX_DEFINE( dns_lock ); - -static void dns_service(int fd, void *cookie) -{ - char *hostname = cookie; - struct hostent *hp; - unsigned zero = 0; - - adb_mutex_lock(&dns_lock); - hp = gethostbyname(hostname); - if(hp == 0) { - writex(fd, &zero, 4); - } else { - writex(fd, hp->h_addr, 4); - } - adb_mutex_unlock(&dns_lock); - adb_close(fd); -} -#else -extern int recovery_mode; - -static void recover_service(int s, void *cookie) -{ - unsigned char buf[4096]; - unsigned count = (unsigned) cookie; - int fd; - - fd = adb_creat("/tmp/update", 0644); - if(fd < 0) { - adb_close(s); - return; - } - - while(count > 0) { - unsigned xfer = (count > 4096) ? 4096 : count; - if(readx(s, buf, xfer)) break; - if(writex(fd, buf, xfer)) break; - count -= xfer; - } - - if(count == 0) { - writex(s, "OKAY", 4); - } else { - writex(s, "FAIL", 4); - } - adb_close(fd); - adb_close(s); - - fd = adb_creat("/tmp/update.begin", 0644); - adb_close(fd); -} - -#endif - -#if 0 -static void echo_service(int fd, void *cookie) -{ - char buf[4096]; - int r; - char *p; - int c; - - for(;;) { - r = read(fd, buf, 4096); - if(r == 0) goto done; - if(r < 0) { - if(errno == EINTR) continue; - else goto done; - } - - c = r; - p = buf; - while(c > 0) { - r = write(fd, p, c); - if(r > 0) { - c -= r; - p += r; - continue; - } - if((r < 0) && (errno == EINTR)) continue; - goto done; - } - } -done: - close(fd); -} -#endif - -static int create_service_thread(void (*func)(int, void *), void *cookie) -{ - stinfo *sti; - adb_thread_t t; - int s[2]; - - if(adb_socketpair(s)) { - printf("cannot create service socket pair\n"); - return -1; - } - - sti = malloc(sizeof(stinfo)); - if(sti == 0) fatal("cannot allocate stinfo"); - sti->func = func; - sti->cookie = cookie; - sti->fd = s[1]; - - if(adb_thread_create( &t, service_bootstrap_func, sti)){ - free(sti); - adb_close(s[0]); - adb_close(s[1]); - printf("cannot create service thread\n"); - return -1; - } - - D("service thread started, %d:%d\n",s[0], s[1]); - return s[0]; -} - -static int create_subprocess(const char *cmd, const char *arg0, const char *arg1) -{ -#ifdef HAVE_WIN32_PROC - fprintf(stderr, "error: create_subprocess not implemented on Win32 (%s %s %s)\n", cmd, arg0, arg1); - return -1; -#else /* !HAVE_WIN32_PROC */ - char *devname; - int ptm; - pid_t pid; - - ptm = unix_open("/dev/ptmx", O_RDWR); // | O_NOCTTY); - if(ptm < 0){ - printf("[ cannot open /dev/ptmx - %s ]\n",strerror(errno)); - return -1; - } - fcntl(ptm, F_SETFD, FD_CLOEXEC); - - if(grantpt(ptm) || unlockpt(ptm) || - ((devname = (char*) ptsname(ptm)) == 0)){ - printf("[ trouble with /dev/ptmx - %s ]\n", strerror(errno)); - return -1; - } - - pid = fork(); - if(pid < 0) { - printf("- fork failed: %s -\n", strerror(errno)); - return -1; - } - - if(pid == 0){ - int pts; - - setsid(); - - pts = unix_open(devname, O_RDWR); - if(pts < 0) exit(-1); - - dup2(pts, 0); - dup2(pts, 1); - dup2(pts, 2); - - adb_close(ptm); - - execl(cmd, cmd, arg0, arg1, NULL); - fprintf(stderr, "- exec '%s' failed: %s (%d) -\n", - cmd, strerror(errno), errno); - exit(-1); - } else { - return ptm; - } -#endif /* !HAVE_WIN32_PROC */ -} - -#if ADB_HOST -#define SHELL_COMMAND "/bin/sh" -#else -#define SHELL_COMMAND "/system/bin/sh" -#endif - -int service_to_fd(const char *name) -{ - int ret = -1; - - if(!strncmp(name, "tcp:", 4)) { - int port = atoi(name + 4); - name = strchr(name + 4, ':'); - if(name == 0) { - ret = socket_loopback_client(port, SOCK_STREAM); - if (ret >= 0) - disable_tcp_nagle(ret); - } else { -#if ADB_HOST - adb_mutex_lock(&dns_lock); - ret = socket_network_client(name + 1, port, SOCK_STREAM); - adb_mutex_unlock(&dns_lock); -#else - return -1; -#endif - } -#ifndef HAVE_WINSOCK /* winsock doesn't implement unix domain sockets */ - } else if(!strncmp(name, "local:", 6)) { - ret = socket_local_client(name + 6, - ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); - } else if(!strncmp(name, "localreserved:", 14)) { - ret = socket_local_client(name + 14, - ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM); - } else if(!strncmp(name, "localabstract:", 14)) { - ret = socket_local_client(name + 14, - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - } else if(!strncmp(name, "localfilesystem:", 16)) { - ret = socket_local_client(name + 16, - ANDROID_SOCKET_NAMESPACE_FILESYSTEM, SOCK_STREAM); -#endif -#if ADB_HOST - } else if(!strncmp("dns:", name, 4)){ - char *n = strdup(name + 4); - if(n == 0) return -1; - ret = create_service_thread(dns_service, n); -#else /* !ADB_HOST */ - } else if(!strncmp("dev:", name, 4)) { - ret = unix_open(name + 4, O_RDWR); - } else if(!strncmp(name, "framebuffer:", 12)) { - ret = create_service_thread(framebuffer_service, 0); - } else if(recovery_mode && !strncmp(name, "recover:", 8)) { - ret = create_service_thread(recover_service, (void*) atoi(name + 8)); - } else if (!strncmp(name, "jdwp:", 5)) { - ret = create_jdwp_connection_fd(atoi(name+5)); - } else if (!strncmp(name, "log:", 4)) { - ret = create_service_thread(log_service, get_log_file_path(name + 4)); -#endif - } else if(!HOST && !strncmp(name, "shell:", 6)) { - if(name[6]) { - ret = create_subprocess(SHELL_COMMAND, "-c", name + 6); - } else { - ret = create_subprocess(SHELL_COMMAND, "-", 0); - } -#if !ADB_HOST - } else if(!strncmp(name, "sync:", 5)) { - ret = create_service_thread(file_sync_service, NULL); - } else if(!strncmp(name, "remount:", 8)) { - ret = create_service_thread(remount_service, NULL); -#endif -#if 0 - } else if(!strncmp(name, "echo:", 5)){ - ret = create_service_thread(echo_service, 0); -#endif - } - if (ret >= 0) { - close_on_exec(ret); - } - return ret; -} - -#if ADB_HOST -struct state_info { - transport_type transport; - char* serial; - int state; -}; - -static void wait_for_state(int fd, void* cookie) -{ - struct state_info* sinfo = cookie; - char* err = "unknown error"; - - D("wait_for_state %d\n", sinfo->state); - - atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err); - if(t != 0) { - writex(fd, "OKAY", 4); - } else { - sendfailmsg(fd, err); - } - - if (sinfo->serial) - free(sinfo->serial); - free(sinfo); - adb_close(fd); - D("wait_for_state is done\n"); -} -#endif - -#if ADB_HOST -asocket* host_service_to_socket(const char* name, const char *serial) -{ - if (!strcmp(name,"track-devices")) { - return create_device_tracker(); - } else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) { - struct state_info* sinfo = malloc(sizeof(struct state_info)); - - if (serial) - sinfo->serial = strdup(serial); - else - sinfo->serial = NULL; - - name += strlen("wait-for-"); - - if (!strncmp(name, "local", strlen("local"))) { - sinfo->transport = kTransportLocal; - sinfo->state = CS_DEVICE; - } else if (!strncmp(name, "usb", strlen("usb"))) { - sinfo->transport = kTransportUsb; - sinfo->state = CS_DEVICE; - } else if (!strncmp(name, "any", strlen("any"))) { - sinfo->transport = kTransportAny; - sinfo->state = CS_DEVICE; - } else { - free(sinfo); - return NULL; - } - - int fd = create_service_thread(wait_for_state, sinfo); - return create_local_socket(fd); - } - return NULL; -} -#endif /* ADB_HOST */ diff --git a/adb/shlist.c b/adb/shlist.c deleted file mode 100755 index 44919ef04606841f59aea4c6e89564cd0e0d8a31..0000000000000000000000000000000000000000 --- a/adb/shlist.c +++ /dev/null @@ -1,185 +0,0 @@ -/*-------------------------------------------------------------------*/ -/* List Functionality */ -/*-------------------------------------------------------------------*/ -/* #define SH_LIST_DEBUG */ -/*-------------------------------------------------------------------*/ -#include <stdio.h> -#include <stdlib.h> -#include "shlist.h" -/*-------------------------------------------------------------------*/ -void shListInitList( SHLIST *listPtr ) -{ - listPtr->data = (void *)0L; - listPtr->next = listPtr; - listPtr->prev = listPtr; -} - -SHLIST *shListFindItem( SHLIST *head, void *val, shListEqual func ) -{ - SHLIST *item; - - for(item=head->next;( item != head );item=item->next) - if( func ) { - if( func( val, item->data ) ) { - return( item ); - } - } - else { - if( item->data == val ) { - return( item ); - } - } - return( NULL ); -} - -SHLIST *shListGetLastItem( SHLIST *head ) -{ - if( head->prev != head ) - return( head->prev ); - return( NULL ); -} - -SHLIST *shListGetFirstItem( SHLIST *head ) -{ - if( head->next != head ) - return( head->next ); - return( NULL ); -} - -SHLIST *shListGetNItem( SHLIST *head, unsigned long num ) -{ - SHLIST *item; - unsigned long i; - - for(i=0,item=head->next;( (i < num) && (item != head) );i++,item=item->next); - if( item != head ) - return( item ); - return( NULL ); -} - -SHLIST *shListGetNextItem( SHLIST *head, SHLIST *item ) -{ - if( item == NULL ) - return( NULL ); - if( item->next != head ) - return( item->next ); - return( NULL ); -} - -SHLIST *shListGetPrevItem( SHLIST *head, SHLIST *item ) -{ - if( item == NULL ) - return( NULL ); - if( item->prev != head ) - return( item->prev ); - return( NULL ); -} - -void shListDelItem( SHLIST *head, SHLIST *item, shListFree func ) -{ - if( item == NULL ) - return; -#ifdef SH_LIST_DEBUG - fprintf(stderr, "Del %lx\n", (unsigned long)(item->data)); -#endif - (item->prev)->next = item->next; - (item->next)->prev = item->prev; - if( func && item->data ) { - func( (void *)(item->data) ); - } - free( item ); - head->data = (void *)((unsigned long)(head->data) - 1); -} - -void shListInsFirstItem( SHLIST *head, void *val ) -{ /* Insert to the beginning of the list */ - SHLIST *item; - - item = (SHLIST *)malloc( sizeof(SHLIST) ); - if( item == NULL ) - return; - item->data = val; - item->next = head->next; - item->prev = head; - (head->next)->prev = item; - head->next = item; -#ifdef SH_LIST_DEBUG - fprintf(stderr, "Ins First %lx\n", (unsigned long)(item->data)); -#endif - head->data = (void *)((unsigned long)(head->data) + 1); -} - -void shListInsLastItem( SHLIST *head, void *val ) -{ /* Insert to the end of the list */ - SHLIST *item; - - item = (SHLIST *)malloc( sizeof(SHLIST) ); - if( item == NULL ) - return; - item->data = val; - item->next = head; - item->prev = head->prev; - (head->prev)->next = item; - head->prev = item; -#ifdef SH_LIST_DEBUG - fprintf(stderr, "Ins Last %lx\n", (unsigned long)(item->data)); -#endif - head->data = (void *)((unsigned long)(head->data) + 1); -} - -void shListInsBeforeItem( SHLIST *head, void *val, void *etal, - shListCmp func ) -{ - SHLIST *item, *iptr; - - if( func == NULL ) - shListInsFirstItem( head, val ); - else { - item = (SHLIST *)malloc( sizeof(SHLIST) ); - if( item == NULL ) - return; - item->data = val; - for(iptr=head->next;( iptr != head );iptr=iptr->next) - if( func( val, iptr->data, etal ) ) - break; - item->next = iptr; - item->prev = iptr->prev; - (iptr->prev)->next = item; - iptr->prev = item; -#ifdef SH_LIST_DEBUG - fprintf(stderr, "Ins Before %lx\n", (unsigned long)(item->data)); -#endif - head->data = (void *)((unsigned long)(head->data) + 1); - } -} - -void shListDelAllItems( SHLIST *head, shListFree func ) -{ - SHLIST *item; - - for(item=head->next;( item != head );) { - shListDelItem( head, item, func ); - item = head->next; - } - head->data = (void *)0L; -} - -void shListPrintAllItems( SHLIST *head, shListPrint func ) -{ -#ifdef SH_LIST_DEBUG - SHLIST *item; - - for(item=head->next;( item != head );item=item->next) - if( func ) { - func(item->data); - } - else { - fprintf(stderr, "Item: %lx\n",(unsigned long)(item->data)); - } -#endif -} - -unsigned long shListGetCount( SHLIST *head ) -{ - return( (unsigned long)(head->data) ); -} diff --git a/adb/shlist.h b/adb/shlist.h deleted file mode 100755 index 0a9b07b27660fdb5b1ae8da853653f61fbc4d782..0000000000000000000000000000000000000000 --- a/adb/shlist.h +++ /dev/null @@ -1,34 +0,0 @@ -/*-------------------------------------------------------------------*/ -/* List Functionality */ -/*-------------------------------------------------------------------*/ -#ifndef _SHLIST_H_ -#define _SHLIST_H_ - -typedef struct SHLIST_STRUC { - void *data; - struct SHLIST_STRUC *next; - struct SHLIST_STRUC *prev; -} SHLIST; - -typedef int (*shListCmp)( void *valo, void *valn, void *etalon ); -typedef int (*shListPrint)( void *val ); -typedef void (*shListFree)( void *val ); -typedef int (*shListEqual)( void *val, void *idata ); - -void shListInitList( SHLIST *listPtr ); -SHLIST *shListFindItem( SHLIST *head, void *val, shListEqual func ); -SHLIST *shListGetFirstItem( SHLIST *head ); -SHLIST *shListGetNItem( SHLIST *head, unsigned long num ); -SHLIST *shListGetLastItem( SHLIST *head ); -SHLIST *shListGetNextItem( SHLIST *head, SHLIST *item ); -SHLIST *shListGetPrevItem( SHLIST *head, SHLIST *item ); -void shListDelItem( SHLIST *head, SHLIST *item, shListFree func ); -void shListInsFirstItem( SHLIST *head, void *val ); -void shListInsBeforeItem( SHLIST *head, void *val, void *etalon, - shListCmp func ); -void shListInsLastItem( SHLIST *head, void *val ); -void shListDelAllItems( SHLIST *head, shListFree func ); -void shListPrintAllItems( SHLIST *head, shListPrint func ); -unsigned long shListGetCount( SHLIST *head ); - -#endif diff --git a/adb/sockets.c b/adb/sockets.c deleted file mode 100644 index 9f1b5987060d438cb6cb4832938f51ba596def68..0000000000000000000000000000000000000000 --- a/adb/sockets.c +++ /dev/null @@ -1,787 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <ctype.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_SOCKETS -#include "adb.h" - -ADB_MUTEX_DEFINE( socket_list_lock ); - -static void local_socket_close_locked(asocket *s); - -int sendfailmsg(int fd, const char *reason) -{ - char buf[9]; - int len; - len = strlen(reason); - if(len > 0xffff) len = 0xffff; - snprintf(buf, sizeof buf, "FAIL%04x", len); - if(writex(fd, buf, 8)) return -1; - return writex(fd, reason, len); -} - -//extern int online; - -static unsigned local_socket_next_id = 1; - -static asocket local_socket_list = { - .next = &local_socket_list, - .prev = &local_socket_list, -}; - -/* the the list of currently closing local sockets. -** these have no peer anymore, but still packets to -** write to their fd. -*/ -static asocket local_socket_closing_list = { - .next = &local_socket_closing_list, - .prev = &local_socket_closing_list, -}; - -asocket *find_local_socket(unsigned id) -{ - asocket *s; - asocket *result = NULL; - - adb_mutex_lock(&socket_list_lock); - for(s = local_socket_list.next; s != &local_socket_list && !result; s = s->next) { - if(s->id == id) result = s; - } - adb_mutex_unlock(&socket_list_lock); - - return result; -} - -static void -insert_local_socket(asocket* s, asocket* list) -{ - s->next = list; - s->prev = s->next->prev; - s->prev->next = s; - s->next->prev = s; -} - - -void install_local_socket(asocket *s) -{ - adb_mutex_lock(&socket_list_lock); - - s->id = local_socket_next_id++; - insert_local_socket(s, &local_socket_list); - - adb_mutex_unlock(&socket_list_lock); -} - -void remove_socket(asocket *s) -{ - // socket_list_lock should already be held - if (s->prev && s->next) - { - s->prev->next = s->next; - s->next->prev = s->prev; - s->next = 0; - s->prev = 0; - s->id = 0; - } -} - -void close_all_sockets(atransport *t) -{ - asocket *s; - - /* this is a little gross, but since s->close() *will* modify - ** the list out from under you, your options are limited. - */ - adb_mutex_lock(&socket_list_lock); -restart: - for(s = local_socket_list.next; s != &local_socket_list; s = s->next){ - if(s->transport == t || (s->peer && s->peer->transport == t)) { - local_socket_close_locked(s); - goto restart; - } - } - adb_mutex_unlock(&socket_list_lock); -} - -static int local_socket_enqueue(asocket *s, apacket *p) -{ - D("LS(%d): enqueue %d\n", s->id, p->len); - - p->ptr = p->data; - - /* if there is already data queue'd, we will receive - ** events when it's time to write. just add this to - ** the tail - */ - if(s->pkt_first) { - goto enqueue; - } - - /* write as much as we can, until we - ** would block or there is an error/eof - */ - while(p->len > 0) { - int r = adb_write(s->fd, p->ptr, p->len); - if(r > 0) { - p->len -= r; - p->ptr += r; - continue; - } - if((r == 0) || (errno != EAGAIN)) { - D( "LS(%d): not ready, errno=%d: %s\n", s->id, errno, strerror(errno) ); - s->close(s); - return 1; /* not ready (error) */ - } else { - break; - } - } - - if(p->len == 0) { - put_apacket(p); - return 0; /* ready for more data */ - } - -enqueue: - p->next = 0; - if(s->pkt_first) { - s->pkt_last->next = p; - } else { - s->pkt_first = p; - } - s->pkt_last = p; - - /* make sure we are notified when we can drain the queue */ - fdevent_add(&s->fde, FDE_WRITE); - - return 1; /* not ready (backlog) */ -} - -static void local_socket_ready(asocket *s) -{ - /* far side is ready for data, pay attention to - readable events */ - fdevent_add(&s->fde, FDE_READ); -// D("LS(%d): ready()\n", s->id); -} - -static void local_socket_close(asocket *s) -{ - adb_mutex_lock(&socket_list_lock); - local_socket_close_locked(s); - adb_mutex_unlock(&socket_list_lock); -} - -// be sure to hold the socket list lock when calling this -static void local_socket_destroy(asocket *s) -{ - apacket *p, *n; - - /* IMPORTANT: the remove closes the fd - ** that belongs to this socket - */ - fdevent_remove(&s->fde); - - /* dispose of any unwritten data */ - for(p = s->pkt_first; p; p = n) { - D("LS(%d): discarding %d bytes\n", s->id, p->len); - n = p->next; - put_apacket(p); - } - remove_socket(s); - free(s); -} - - -static void local_socket_close_locked(asocket *s) -{ - if(s->peer) { - s->peer->peer = 0; - // tweak to avoid deadlock - if (s->peer->close == local_socket_close) - local_socket_close_locked(s->peer); - else - s->peer->close(s->peer); - } - - /* If we are already closing, or if there are no - ** pending packets, destroy immediately - */ - if (s->closing || s->pkt_first == NULL) { - int id = s->id; - local_socket_destroy(s); - D("LS(%d): closed\n", id); - return; - } - - /* otherwise, put on the closing list - */ - D("LS(%d): closing\n", s->id); - s->closing = 1; - fdevent_del(&s->fde, FDE_READ); - remove_socket(s); - insert_local_socket(s, &local_socket_closing_list); -} - -static void local_socket_event_func(int fd, unsigned ev, void *_s) -{ - asocket *s = _s; - - /* put the FDE_WRITE processing before the FDE_READ - ** in order to simplify the code. - */ - if(ev & FDE_WRITE){ - apacket *p; - - while((p = s->pkt_first) != 0) { - while(p->len > 0) { - int r = adb_write(fd, p->ptr, p->len); - if(r > 0) { - p->ptr += r; - p->len -= r; - continue; - } - if(r < 0) { - /* returning here is ok because FDE_READ will - ** be processed in the next iteration loop - */ - if(errno == EAGAIN) return; - if(errno == EINTR) continue; - } - s->close(s); - return; - } - - if(p->len == 0) { - s->pkt_first = p->next; - if(s->pkt_first == 0) s->pkt_last = 0; - put_apacket(p); - } - } - - /* if we sent the last packet of a closing socket, - ** we can now destroy it. - */ - if (s->closing) { - s->close(s); - return; - } - - /* no more packets queued, so we can ignore - ** writable events again and tell our peer - ** to resume writing - */ - fdevent_del(&s->fde, FDE_WRITE); - s->peer->ready(s->peer); - } - - - if(ev & FDE_READ){ - apacket *p = get_apacket(); - unsigned char *x = p->data; - size_t avail = MAX_PAYLOAD; - int r; - int is_eof = 0; - - while(avail > 0) { - r = adb_read(fd, x, avail); - if(r > 0) { - avail -= r; - x += r; - continue; - } - if(r < 0) { - if(errno == EAGAIN) break; - if(errno == EINTR) continue; - } - - /* r = 0 or unhandled error */ - is_eof = 1; - break; - } - - if((avail == MAX_PAYLOAD) || (s->peer == 0)) { - put_apacket(p); - } else { - p->len = MAX_PAYLOAD - avail; - - r = s->peer->enqueue(s->peer, p); - - if(r < 0) { - /* error return means they closed us as a side-effect - ** and we must return immediately. - ** - ** note that if we still have buffered packets, the - ** socket will be placed on the closing socket list. - ** this handler function will be called again - ** to process FDE_WRITE events. - */ - return; - } - - if(r > 0) { - /* if the remote cannot accept further events, - ** we disable notification of READs. They'll - ** be enabled again when we get a call to ready() - */ - fdevent_del(&s->fde, FDE_READ); - } - } - - if(is_eof) { - s->close(s); - } - } - - if(ev & FDE_ERROR){ - /* this should be caught be the next read or write - ** catching it here means we may skip the last few - ** bytes of readable data. - */ -// s->close(s); - return; - } -} - -asocket *create_local_socket(int fd) -{ - asocket *s = calloc(1, sizeof(asocket)); - if(s == 0) fatal("cannot allocate socket"); - install_local_socket(s); - s->fd = fd; - s->enqueue = local_socket_enqueue; - s->ready = local_socket_ready; - s->close = local_socket_close; - - fdevent_install(&s->fde, fd, local_socket_event_func, s); -/* fdevent_add(&s->fde, FDE_ERROR); */ - //fprintf(stderr, "Created local socket in create_local_socket \n"); - D("LS(%d): created (fd=%d)\n", s->id, s->fd); - return s; -} - -asocket *create_local_service_socket(const char *name) -{ - asocket *s; - int fd; - -#if !ADB_HOST - if (!strcmp(name,"jdwp")) { - return create_jdwp_service_socket(); - } - if (!strcmp(name,"track-jdwp")) { - return create_jdwp_tracker_service_socket(); - } -#endif - fd = service_to_fd(name); - if(fd < 0) return 0; - - s = create_local_socket(fd); - D("LS(%d): bound to '%s'\n", s->id, name); - return s; -} - -#if ADB_HOST -static asocket *create_host_service_socket(const char *name, const char* serial) -{ - asocket *s; - - s = host_service_to_socket(name, serial); - - if (s != NULL) { - D("LS(%d) bound to '%s'\n", s->id, name); - return s; - } - - return s; -} -#endif /* ADB_HOST */ - -/* a Remote socket is used to send/receive data to/from a given transport object -** it needs to be closed when the transport is forcibly destroyed by the user -*/ -typedef struct aremotesocket { - asocket socket; - adisconnect disconnect; -} aremotesocket; - -static int remote_socket_enqueue(asocket *s, apacket *p) -{ - D("Calling remote_socket_enqueue\n"); - p->msg.command = A_WRTE; - p->msg.arg0 = s->peer->id; - p->msg.arg1 = s->id; - p->msg.data_length = p->len; - send_packet(p, s->transport); - return 1; -} - -static void remote_socket_ready(asocket *s) -{ - D("Calling remote_socket_ready\n"); - apacket *p = get_apacket(); - p->msg.command = A_OKAY; - p->msg.arg0 = s->peer->id; - p->msg.arg1 = s->id; - send_packet(p, s->transport); -} - -static void remote_socket_close(asocket *s) -{ - D("Calling remote_socket_close\n"); - apacket *p = get_apacket(); - p->msg.command = A_CLSE; - if(s->peer) { - p->msg.arg0 = s->peer->id; - s->peer->peer = 0; - s->peer->close(s->peer); - } - p->msg.arg1 = s->id; - send_packet(p, s->transport); - D("RS(%d): closed\n", s->id); - remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); - free(s); -} - -static void remote_socket_disconnect(void* _s, atransport* t) -{ - asocket* s = _s; - asocket* peer = s->peer; - - D("remote_socket_disconnect RS(%d)\n", s->id); - if (peer) { - peer->peer = NULL; - peer->close(peer); - } - remove_transport_disconnect( s->transport, &((aremotesocket*)s)->disconnect ); - free(s); -} - -asocket *create_remote_socket(unsigned id, atransport *t) -{ - asocket *s = calloc(1, sizeof(aremotesocket)); - adisconnect* dis = &((aremotesocket*)s)->disconnect; - - if(s == 0) fatal("cannot allocate socket"); - s->id = id; - s->enqueue = remote_socket_enqueue; - s->ready = remote_socket_ready; - s->close = remote_socket_close; - s->transport = t; - - dis->func = remote_socket_disconnect; - dis->opaque = s; - add_transport_disconnect( t, dis ); - D("RS(%d): created\n", s->id); - return s; -} - -void connect_to_remote(asocket *s, const char *destination) -{ - D("Connect_to_remote call \n"); - apacket *p = get_apacket(); - int len = strlen(destination) + 1; - - if(len > (MAX_PAYLOAD-1)) { - fatal("destination oversized"); - } - - D("LS(%d): connect('%s')\n", s->id, destination); - p->msg.command = A_OPEN; - p->msg.arg0 = s->id; - p->msg.data_length = len; - strcpy((char*) p->data, destination); - send_packet(p, s->transport); -} - - -/* this is used by magic sockets to rig local sockets to - send the go-ahead message when they connect */ -static void local_socket_ready_notify(asocket *s) -{ - s->ready = local_socket_ready; - s->close = local_socket_close; - adb_write(s->fd, "OKAY", 4); - s->ready(s); -} - -/* this is used by magic sockets to rig local sockets to - send the failure message if they are closed before - connected (to avoid closing them without a status message) */ -static void local_socket_close_notify(asocket *s) -{ - s->ready = local_socket_ready; - s->close = local_socket_close; - sendfailmsg(s->fd, "closed"); - s->close(s); -} - -unsigned unhex(unsigned char *s, int len) -{ - unsigned n = 0, c; - - while(len-- > 0) { - switch((c = *s++)) { - case '0': case '1': case '2': - case '3': case '4': case '5': - case '6': case '7': case '8': - case '9': - c -= '0'; - break; - case 'a': case 'b': case 'c': - case 'd': case 'e': case 'f': - c = c - 'a' + 10; - break; - case 'A': case 'B': case 'C': - case 'D': case 'E': case 'F': - c = c - 'A' + 10; - break; - default: - return 0xffffffff; - } - - n = (n << 4) | c; - } - - return n; -} - -static int smart_socket_enqueue(asocket *s, apacket *p) -{ - unsigned len; -#if ADB_HOST - char *service = NULL; - char* serial = NULL; - transport_type ttype = kTransportAny; -#endif - - D("SS(%d): enqueue %d\n", s->id, p->len); - - if(s->pkt_first == 0) { - s->pkt_first = p; - s->pkt_last = p; - } else { - if((s->pkt_first->len + p->len) > MAX_PAYLOAD) { - D("SS(%d): overflow\n", s->id); - put_apacket(p); - goto fail; - } - - memcpy(s->pkt_first->data + s->pkt_first->len, - p->data, p->len); - s->pkt_first->len += p->len; - put_apacket(p); - - p = s->pkt_first; - } - - /* don't bother if we can't decode the length */ - if(p->len < 4) return 0; - - len = unhex(p->data, 4); - if((len < 1) || (len > 1024)) { - D("SS(%d): bad size (%d)\n", s->id, len); - goto fail; - } - - D("SS(%d): len is %d\n", s->id, len ); - /* can't do anything until we have the full header */ - if((len + 4) > p->len) { - D("SS(%d): waiting for %d more bytes\n", s->id, len+4 - p->len); - return 0; - } - - p->data[len + 4] = 0; - - D("SS(%d): '%s'\n", s->id, (char*) (p->data + 4)); - -#if ADB_HOST - service = (char *)p->data + 4; - if(!strncmp(service, "host-serial:", strlen("host-serial:"))) { - char* serial_end; - service += strlen("host-serial:"); - - // serial number should follow "host:" - serial_end = strchr(service, ':'); - if (serial_end) { - *serial_end = 0; // terminate string - serial = service; - service = serial_end + 1; - } - } else if (!strncmp(service, "host-usb:", strlen("host-usb:"))) { - ttype = kTransportUsb; - service += strlen("host-usb:"); - } else if (!strncmp(service, "host-local:", strlen("host-local:"))) { - ttype = kTransportLocal; - service += strlen("host-local:"); - } else if (!strncmp(service, "host:", strlen("host:"))) { - ttype = kTransportAny; - service += strlen("host:"); - } else { - service = NULL; - } - - if (service) { - asocket *s2; - - /* some requests are handled immediately -- in that - ** case the handle_host_request() routine has sent - ** the OKAY or FAIL message and all we have to do - ** is clean up. - */ - if(handle_host_request(service, ttype, serial, s->peer->fd, s) == 0) { - /* XXX fail message? */ - D( "SS(%d): handled host service '%s'\n", s->id, service ); - goto fail; - } - if (!strncmp(service, "transport", strlen("transport"))) { - D( "SS(%d): okay transport\n", s->id ); - p->len = 0; - return 0; - } - - /* try to find a local service with this name. - ** if no such service exists, we'll fail out - ** and tear down here. - */ - s2 = create_host_service_socket(service, serial); - if(s2 == 0) { - D( "SS(%d): couldn't create host service '%s'\n", s->id, service ); - sendfailmsg(s->peer->fd, "unknown host service"); - goto fail; - } - - /* we've connected to a local host service, - ** so we make our peer back into a regular - ** local socket and bind it to the new local - ** service socket, acknowledge the successful - ** connection, and close this smart socket now - ** that its work is done. - */ - adb_write(s->peer->fd, "OKAY", 4); - - s->peer->ready = local_socket_ready; - s->peer->close = local_socket_close; - s->peer->peer = s2; - s2->peer = s->peer; - s->peer = 0; - D( "SS(%d): okay\n", s->id ); - s->close(s); - - /* initial state is "ready" */ - s2->ready(s2); - return 0; - } -#else /* !ADB_HOST */ - if (s->transport == NULL) { - char* error_string = "unknown failure"; - s->transport = acquire_one_transport (CS_ANY, - kTransportAny, NULL, &error_string); - - if (s->transport == NULL) { - sendfailmsg(s->peer->fd, error_string); - goto fail; - } - } -#endif - - if(!(s->transport) || (s->transport->connection_state == CS_OFFLINE)) { - /* if there's no remote we fail the connection - ** right here and terminate it - */ - sendfailmsg(s->peer->fd, "device offline (x)"); - goto fail; - } - - - /* instrument our peer to pass the success or fail - ** message back once it connects or closes, then - ** detach from it, request the connection, and - ** tear down - */ - s->peer->ready = local_socket_ready_notify; - s->peer->close = local_socket_close_notify; - s->peer->peer = 0; - /* give him our transport and upref it */ - s->peer->transport = s->transport; - - connect_to_remote(s->peer, (char*) (p->data + 4)); - s->peer = 0; - s->close(s); - return 1; - -fail: - /* we're going to close our peer as a side-effect, so - ** return -1 to signal that state to the local socket - ** who is enqueueing against us - */ - s->close(s); - return -1; -} - -static void smart_socket_ready(asocket *s) -{ - D("SS(%d): ready\n", s->id); -} - -static void smart_socket_close(asocket *s) -{ - D("SS(%d): closed\n", s->id); - if(s->pkt_first){ - put_apacket(s->pkt_first); - } - if(s->peer) { - s->peer->peer = 0; - s->peer->close(s->peer); - } - free(s); -} - -asocket *create_smart_socket(void (*action_cb)(asocket *s, const char *act)) -{ - D("Creating smart socket \n"); - asocket *s = calloc(1, sizeof(asocket)); - if(s == 0) fatal("cannot allocate socket"); - s->id = 0; - s->enqueue = smart_socket_enqueue; - s->ready = smart_socket_ready; - s->close = smart_socket_close; - s->extra = action_cb; - - D("SS(%d): created %p\n", s->id, action_cb); - return s; -} - -void smart_socket_action(asocket *s, const char *act) -{ - -} - -void connect_to_smartsocket(asocket *s) -{ - D("Connecting to smart socket \n"); - asocket *ss = create_smart_socket(smart_socket_action); - s->peer = ss; - ss->peer = s; - s->ready(s); -} diff --git a/adb/sockets.dia b/adb/sockets.dia deleted file mode 100644 index c626f20f0aa3ba846658cd95bb60d1792128afc5..0000000000000000000000000000000000000000 Binary files a/adb/sockets.dia and /dev/null differ diff --git a/adb/sysdeps.h b/adb/sysdeps.h deleted file mode 100644 index e5d17a85b7f9eac3bb80d04a1a48707f65cee756..0000000000000000000000000000000000000000 --- a/adb/sysdeps.h +++ /dev/null @@ -1,473 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* this file contains system-dependent definitions used by ADB - * they're related to threads, sockets and file descriptors - */ -#ifndef _ADB_SYSDEPS_H -#define _ADB_SYSDEPS_H - -#ifdef __CYGWIN__ -# undef _WIN32 -#endif - -#ifdef _WIN32 - -#include <windows.h> -#include <winsock2.h> -#include <ws2tcpip.h> -#include <process.h> -#include <fcntl.h> -#include <io.h> -#include <sys/stat.h> -#include <errno.h> -#include <ctype.h> - -#define OS_PATH_SEPARATOR '\\' -#define OS_PATH_SEPARATOR_STR "\\" - -typedef CRITICAL_SECTION adb_mutex_t; - -#define ADB_MUTEX_DEFINE(x) adb_mutex_t x - -/* declare all mutexes */ -#define ADB_MUTEX(x) extern adb_mutex_t x; -#include "mutex_list.h" - -extern void adb_sysdeps_init(void); - -static __inline__ void adb_mutex_lock( adb_mutex_t* lock ) -{ - EnterCriticalSection( lock ); -} - -static __inline__ void adb_mutex_unlock( adb_mutex_t* lock ) -{ - LeaveCriticalSection( lock ); -} - -typedef struct { unsigned tid; } adb_thread_t; - -typedef void* (*adb_thread_func_t)(void* arg); - -typedef void (*win_thread_func_t)(void* arg); - -static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func_t func, void* arg) -{ - thread->tid = _beginthread( (win_thread_func_t)func, 0, arg ); - if (thread->tid == (unsigned)-1L) { - return -1; - } - return 0; -} - -static __inline__ void close_on_exec(int fd) -{ - /* nothing really */ -} - -extern void disable_tcp_nagle(int fd); - -#define lstat stat /* no symlinks on Win32 */ - -#define S_ISLNK(m) 0 /* no symlinks on Win32 */ - -static __inline__ int adb_unlink(const char* path) -{ - int rc = unlink(path); - - if (rc == -1 && errno == EACCES) { - /* unlink returns EACCES when the file is read-only, so we first */ - /* try to make it writable, then unlink again... */ - rc = chmod(path, _S_IREAD|_S_IWRITE ); - if (rc == 0) - rc = unlink(path); - } - return rc; -} -#undef unlink -#define unlink ___xxx_unlink - -static __inline__ int adb_mkdir(const char* path, int mode) -{ - return _mkdir(path); -} -#undef mkdir -#define mkdir ___xxx_mkdir - -extern int adb_open(const char* path, int options); -extern int adb_creat(const char* path, int mode); -extern int adb_read(int fd, void* buf, int len); -extern int adb_write(int fd, const void* buf, int len); -extern int adb_lseek(int fd, int pos, int where); -extern int adb_close(int fd); - -static __inline__ int unix_close(int fd) -{ - return close(fd); -} -#undef close -#define close ____xxx_close - -static __inline__ int unix_read(int fd, void* buf, size_t len) -{ - return read(fd, buf, len); -} -#undef read -#define read ___xxx_read - -static __inline__ int unix_write(int fd, const void* buf, size_t len) -{ - return write(fd, buf, len); -} -#undef write -#define write ___xxx_write - -static __inline__ int adb_open_mode(const char* path, int options, int mode) -{ - return adb_open(path, options); -} - -static __inline__ int unix_open(const char* path, int options,...) -{ - if ((options & O_CREAT) == 0) - { - return open(path, options); - } - else - { - int mode; - va_list args; - va_start( args, options ); - mode = va_arg( args, int ); - va_end( args ); - return open(path, options, mode); - } -} -#define open ___xxx_unix_open - - -/* normally provided by <cutils/misc.h> */ -extern void* load_file(const char* pathname, unsigned* psize); - -/* normally provided by <cutils/sockets.h> */ -extern int socket_loopback_client(int port, int type); -extern int socket_network_client(const char *host, int port, int type); -extern int socket_loopback_server(int port, int type); -extern int socket_inaddr_any_server(int port, int type); - -/* normally provided by <cutils/fdevent.h> */ - -#define FDE_READ 0x0001 -#define FDE_WRITE 0x0002 -#define FDE_ERROR 0x0004 -#define FDE_DONT_CLOSE 0x0080 - -typedef struct fdevent fdevent; - -typedef void (*fd_func)(int fd, unsigned events, void *userdata); - -fdevent *fdevent_create(int fd, fd_func func, void *arg); -void fdevent_destroy(fdevent *fde); -void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg); -void fdevent_remove(fdevent *item); -void fdevent_set(fdevent *fde, unsigned events); -void fdevent_add(fdevent *fde, unsigned events); -void fdevent_del(fdevent *fde, unsigned events); -void fdevent_loop(); - -struct fdevent { - fdevent *next; - fdevent *prev; - - int fd; - unsigned short state; - unsigned short events; - - fd_func func; - void *arg; -}; - -static __inline__ void adb_sleep_ms( int mseconds ) -{ - Sleep( mseconds ); -} - -extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen); - -#undef accept -#define accept ___xxx_accept - -static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) -{ - int opt = bufsize; - return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const char*)&opt, sizeof(opt)); -} - -extern int adb_socketpair( int sv[2] ); - -static __inline__ char* adb_dirstart( const char* path ) -{ - char* p = strchr(path, '/'); - char* p2 = strchr(path, '\\'); - - if ( !p ) - p = p2; - else if ( p2 && p2 > p ) - p = p2; - - return p; -} - -static __inline__ char* adb_dirstop( const char* path ) -{ - char* p = strrchr(path, '/'); - char* p2 = strrchr(path, '\\'); - - if ( !p ) - p = p2; - else if ( p2 && p2 > p ) - p = p2; - - return p; -} - -static __inline__ int adb_is_absolute_host_path( const char* path ) -{ - return isalpha(path[0]) && path[1] == ':' && path[2] == '\\'; -} - -#else /* !_WIN32 a.k.a. Unix */ - -#include <cutils/fdevent.h> -#include <cutils/sockets.h> -#include <cutils/properties.h> -#include <cutils/misc.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/stat.h> -#include <fcntl.h> - -#include <pthread.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <netinet/in.h> -#include <netinet/tcp.h> -#include <string.h> - -#define OS_PATH_SEPARATOR '/' -#define OS_PATH_SEPARATOR_STR "/" - -typedef pthread_mutex_t adb_mutex_t; -#define ADB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER -#define adb_mutex_init pthread_mutex_init -#define adb_mutex_lock pthread_mutex_lock -#define adb_mutex_unlock pthread_mutex_unlock -#define adb_mutex_destroy pthread_mutex_destroy - -#define ADB_MUTEX_DEFINE(m) static adb_mutex_t m = PTHREAD_MUTEX_INITIALIZER - -#define adb_cond_t pthread_cond_t -#define adb_cond_init pthread_cond_init -#define adb_cond_wait pthread_cond_wait -#define adb_cond_broadcast pthread_cond_broadcast -#define adb_cond_signal pthread_cond_signal -#define adb_cond_destroy pthread_cond_destroy - -static __inline__ void close_on_exec(int fd) -{ - fcntl( fd, F_SETFD, FD_CLOEXEC ); -} - -static __inline__ int unix_open(const char* path, int options,...) -{ - if ((options & O_CREAT) == 0) - { - return open(path, options); - } - else - { - int mode; - va_list args; - va_start( args, options ); - mode = va_arg( args, int ); - va_end( args ); - return open(path, options, mode); - } -} - -static __inline__ int adb_open_mode( const char* pathname, int options, int mode ) -{ - return open( pathname, options, mode ); -} - - -static __inline__ int adb_open( const char* pathname, int options ) -{ - int fd = open( pathname, options ); - if (fd < 0) - return -1; - close_on_exec( fd ); - return fd; -} -#undef open -#define open ___xxx_open - -static __inline__ int adb_close(int fd) -{ - return close(fd); -} -#undef close -#define close ____xxx_close - - -static __inline__ int adb_read(int fd, void* buf, size_t len) -{ - return read(fd, buf, len); -} - -#undef read -#define read ___xxx_read - -static __inline__ int adb_write(int fd, const void* buf, size_t len) -{ - return write(fd, buf, len); -} -#undef write -#define write ___xxx_write - -static __inline__ int adb_lseek(int fd, int pos, int where) -{ - return lseek(fd, pos, where); -} -#undef lseek -#define lseek ___xxx_lseek - -static __inline__ int adb_unlink(const char* path) -{ - return unlink(path); -} -#undef unlink -#define unlink ___xxx_unlink - -static __inline__ int adb_creat(const char* path, int mode) -{ - int fd = creat(path, mode); - - if ( fd < 0 ) - return -1; - - close_on_exec(fd); - return fd; -} -#undef creat -#define creat ___xxx_creat - -static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) -{ - return accept( serverfd, addr, addrlen ); -} - -#undef accept -#define accept ___xxx_accept - -#define unix_read adb_read -#define unix_write adb_write -#define unix_close adb_close - -typedef pthread_t adb_thread_t; - -typedef void* (*adb_thread_func_t)( void* arg ); - -static __inline__ int adb_thread_create( adb_thread_t *pthread, adb_thread_func_t start, void* arg ) -{ - pthread_attr_t attr; - - pthread_attr_init (&attr); - pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); - - return pthread_create( pthread, &attr, start, arg ); -} - -static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) -{ - int opt = bufsize; - return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)); -} - -static __inline__ void disable_tcp_nagle(int fd) -{ - int on = 1; - setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) ); -} - - -static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] ) -{ - return socketpair( d, type, protocol, sv ); -} - -static __inline__ int adb_socketpair( int sv[2] ) -{ - int rc; - - rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); - if (rc < 0) - return -1; - - close_on_exec( sv[0] ); - close_on_exec( sv[1] ); - return 0; -} - -#undef socketpair -#define socketpair ___xxx_socketpair - -static __inline__ void adb_sleep_ms( int mseconds ) -{ - usleep( mseconds*1000 ); -} - -static __inline__ int adb_mkdir(const char* path, int mode) -{ - return mkdir(path, mode); -} -#undef mkdir -#define mkdir ___xxx_mkdir - -static __inline__ void adb_sysdeps_init(void) -{ -} - -static __inline__ char* adb_dirstart(const char* path) -{ - return strchr(path, '/'); -} - -static __inline__ char* adb_dirstop(const char* path) -{ - return strrchr(path, '/'); -} - -static __inline__ int adb_is_absolute_host_path( const char* path ) -{ - return path[0] == '/'; -} - -#endif /* !_WIN32 */ - -#endif /* _ADB_SYSDEPS_H */ diff --git a/adb/sysdeps_win32.c b/adb/sysdeps_win32.c deleted file mode 100644 index c2a9a985f58043c2aa23c1f2b6151630b4c10ce9..0000000000000000000000000000000000000000 --- a/adb/sysdeps_win32.c +++ /dev/null @@ -1,1953 +0,0 @@ -#include "sysdeps.h" -#include <windows.h> -#include <winsock2.h> -#include <stdio.h> -#include <errno.h> -#define TRACE_TAG TRACE_SYSDEPS -#include "adb.h" - -extern void fatal(const char *fmt, ...); - -#define assert(cond) do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0) - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** replaces libs/cutils/load_file.c *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -void *load_file(const char *fn, unsigned *_sz) -{ - HANDLE file; - char *data; - DWORD file_size; - - file = CreateFile( fn, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - 0, - NULL ); - - if (file == INVALID_HANDLE_VALUE) - return NULL; - - file_size = GetFileSize( file, NULL ); - data = NULL; - - if (file_size > 0) { - data = (char*) malloc( file_size + 1 ); - if (data == NULL) { - D("load_file: could not allocate %ld bytes\n", file_size ); - file_size = 0; - } else { - DWORD out_bytes; - - if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) || - out_bytes != file_size ) - { - D("load_file: could not read %ld bytes from '%s'\n", file_size, fn); - free(data); - data = NULL; - file_size = 0; - } - } - } - CloseHandle( file ); - - *_sz = (unsigned) file_size; - return data; -} - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** common file descriptor handling *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -typedef const struct FHClassRec_* FHClass; - -typedef struct FHRec_* FH; - -typedef struct EventHookRec_* EventHook; - -typedef struct FHClassRec_ -{ - void (*_fh_init) ( FH f ); - int (*_fh_close)( FH f ); - int (*_fh_lseek)( FH f, int pos, int origin ); - int (*_fh_read) ( FH f, void* buf, int len ); - int (*_fh_write)( FH f, const void* buf, int len ); - void (*_fh_hook) ( FH f, int events, EventHook hook ); - -} FHClassRec; - -/* used to emulate unix-domain socket pairs */ -typedef struct SocketPairRec_* SocketPair; - -typedef struct FHRec_ -{ - FHClass clazz; - int used; - int eof; - union { - HANDLE handle; - SOCKET socket; - SocketPair pair; - } u; - - HANDLE event; - int mask; - - char name[32]; - -} FHRec; - -#define fh_handle u.handle -#define fh_socket u.socket -#define fh_pair u.pair - -#define WIN32_FH_BASE 100 - -#define WIN32_MAX_FHS 128 - -static adb_mutex_t _win32_lock; -static FHRec _win32_fhs[ WIN32_MAX_FHS ]; -static int _win32_fh_count; - -static FH -_fh_from_int( int fd ) -{ - FH f; - - fd -= WIN32_FH_BASE; - - if (fd < 0 || fd >= _win32_fh_count) { - D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE ); - errno = EBADF; - return NULL; - } - - f = &_win32_fhs[fd]; - - if (f->used == 0) { - D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE ); - errno = EBADF; - return NULL; - } - - return f; -} - - -static int -_fh_to_int( FH f ) -{ - if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS) - return (int)(f - _win32_fhs) + WIN32_FH_BASE; - - return -1; -} - -static FH -_fh_alloc( FHClass clazz ) -{ - int nn; - FH f = NULL; - - adb_mutex_lock( &_win32_lock ); - - if (_win32_fh_count < WIN32_MAX_FHS) { - f = &_win32_fhs[ _win32_fh_count++ ]; - goto Exit; - } - - for (nn = 0; nn < WIN32_MAX_FHS; nn++) { - if ( _win32_fhs[nn].clazz == NULL) { - f = &_win32_fhs[nn]; - goto Exit; - } - } - D( "_fh_alloc: no more free file descriptors\n" ); -Exit: - if (f) { - f->clazz = clazz; - f->used = 1; - f->eof = 0; - clazz->_fh_init(f); - } - adb_mutex_unlock( &_win32_lock ); - return f; -} - - -static int -_fh_close( FH f ) -{ - if ( f->used ) { - f->clazz->_fh_close( f ); - f->used = 0; - f->eof = 0; - f->clazz = NULL; - } - return 0; -} - -/* forward definitions */ -static const FHClassRec _fh_file_class; -static const FHClassRec _fh_socket_class; - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** file-based descriptor handling *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -static void -_fh_file_init( FH f ) -{ - f->fh_handle = INVALID_HANDLE_VALUE; -} - -static int -_fh_file_close( FH f ) -{ - CloseHandle( f->fh_handle ); - f->fh_handle = INVALID_HANDLE_VALUE; - return 0; -} - -static int -_fh_file_read( FH f, void* buf, int len ) -{ - DWORD read_bytes; - - if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) { - D( "adb_read: could not read %d bytes from %s\n", len, f->name ); - errno = EIO; - return -1; - } else if (read_bytes < (DWORD)len) { - f->eof = 1; - } - return (int)read_bytes; -} - -static int -_fh_file_write( FH f, const void* buf, int len ) -{ - DWORD wrote_bytes; - - if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) { - D( "adb_file_write: could not write %d bytes from %s\n", len, f->name ); - errno = EIO; - return -1; - } else if (wrote_bytes < (DWORD)len) { - f->eof = 1; - } - return (int)wrote_bytes; -} - -static int -_fh_file_lseek( FH f, int pos, int origin ) -{ - DWORD method; - DWORD result; - - switch (origin) - { - case SEEK_SET: method = FILE_BEGIN; break; - case SEEK_CUR: method = FILE_CURRENT; break; - case SEEK_END: method = FILE_END; break; - default: - errno = EINVAL; - return -1; - } - - result = SetFilePointer( f->fh_handle, pos, NULL, method ); - if (result == INVALID_SET_FILE_POINTER) { - errno = EIO; - return -1; - } else { - f->eof = 0; - } - return (int)result; -} - -static void _fh_file_hook( FH f, int event, EventHook eventhook ); /* forward */ - -static const FHClassRec _fh_file_class = -{ - _fh_file_init, - _fh_file_close, - _fh_file_lseek, - _fh_file_read, - _fh_file_write, - _fh_file_hook -}; - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** file-based descriptor handling *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -int adb_open(const char* path, int options) -{ - FH f; - - DWORD desiredAccess = 0; - DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; - - switch (options) { - case O_RDONLY: - desiredAccess = GENERIC_READ; - break; - case O_WRONLY: - desiredAccess = GENERIC_WRITE; - break; - case O_RDWR: - desiredAccess = GENERIC_READ | GENERIC_WRITE; - break; - default: - D("adb_open: invalid options (0x%0x)\n", options); - errno = EINVAL; - return -1; - } - - f = _fh_alloc( &_fh_file_class ); - if ( !f ) { - errno = ENOMEM; - return -1; - } - - f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING, - 0, NULL ); - - if ( f->fh_handle == INVALID_HANDLE_VALUE ) { - _fh_close(f); - D( "adb_open: could not open '%s':", path ); - switch (GetLastError()) { - case ERROR_FILE_NOT_FOUND: - D( "file not found\n" ); - errno = ENOENT; - return -1; - - case ERROR_PATH_NOT_FOUND: - D( "path not found\n" ); - errno = ENOTDIR; - return -1; - - default: - D( "unknown error\n" ); - errno = ENOENT; - return -1; - } - } - - snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path ); - D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) ); - return _fh_to_int(f); -} - -/* ignore mode on Win32 */ -int adb_creat(const char* path, int mode) -{ - FH f; - - f = _fh_alloc( &_fh_file_class ); - if ( !f ) { - errno = ENOMEM; - return -1; - } - - f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, - NULL ); - - if ( f->fh_handle == INVALID_HANDLE_VALUE ) { - _fh_close(f); - D( "adb_creat: could not open '%s':", path ); - switch (GetLastError()) { - case ERROR_FILE_NOT_FOUND: - D( "file not found\n" ); - errno = ENOENT; - return -1; - - case ERROR_PATH_NOT_FOUND: - D( "path not found\n" ); - errno = ENOTDIR; - return -1; - - default: - D( "unknown error\n" ); - errno = ENOENT; - return -1; - } - } - snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path ); - D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) ); - return _fh_to_int(f); -} - - -int adb_read(int fd, void* buf, int len) -{ - FH f = _fh_from_int(fd); - - if (f == NULL) { - return -1; - } - - return f->clazz->_fh_read( f, buf, len ); -} - - -int adb_write(int fd, const void* buf, int len) -{ - FH f = _fh_from_int(fd); - - if (f == NULL) { - return -1; - } - - return f->clazz->_fh_write(f, buf, len); -} - - -int adb_lseek(int fd, int pos, int where) -{ - FH f = _fh_from_int(fd); - - if (!f) { - return -1; - } - - return f->clazz->_fh_lseek(f, pos, where); -} - - -int adb_close(int fd) -{ - FH f = _fh_from_int(fd); - - if (!f) { - return -1; - } - - D( "adb_close: %s\n", f->name); - _fh_close(f); - return 0; -} - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** socket-based file descriptors *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -static void -_socket_set_errno( void ) -{ - switch (WSAGetLastError()) { - case 0: errno = 0; break; - case WSAEWOULDBLOCK: errno = EAGAIN; break; - case WSAEINTR: errno = EINTR; break; - default: - D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() ); - errno = EINVAL; - } -} - -static void -_fh_socket_init( FH f ) -{ - f->fh_socket = INVALID_SOCKET; - f->event = WSACreateEvent(); - f->mask = 0; -} - -static int -_fh_socket_close( FH f ) -{ - /* gently tell any peer that we're closing the socket */ - shutdown( f->fh_socket, SD_BOTH ); - closesocket( f->fh_socket ); - f->fh_socket = INVALID_SOCKET; - CloseHandle( f->event ); - f->mask = 0; - return 0; -} - -static int -_fh_socket_lseek( FH f, int pos, int origin ) -{ - errno = EPIPE; - return -1; -} - -static int -_fh_socket_read( FH f, void* buf, int len ) -{ - int result = recv( f->fh_socket, buf, len, 0 ); - if (result == SOCKET_ERROR) { - _socket_set_errno(); - result = -1; - } - return result; -} - -static int -_fh_socket_write( FH f, const void* buf, int len ) -{ - int result = send( f->fh_socket, buf, len, 0 ); - if (result == SOCKET_ERROR) { - _socket_set_errno(); - result = -1; - } - return result; -} - -static void _fh_socket_hook( FH f, int event, EventHook hook ); /* forward */ - -static const FHClassRec _fh_socket_class = -{ - _fh_socket_init, - _fh_socket_close, - _fh_socket_lseek, - _fh_socket_read, - _fh_socket_write, - _fh_socket_hook -}; - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** replacement for libs/cutils/socket_xxxx.c *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -#include <winsock2.h> - -static int _winsock_init; - -static void -_cleanup_winsock( void ) -{ - WSACleanup(); -} - -static void -_init_winsock( void ) -{ - if (!_winsock_init) { - WSADATA wsaData; - int rc = WSAStartup( MAKEWORD(2,2), &wsaData); - if (rc != 0) { - fatal( "adb: could not initialize Winsock\n" ); - } - atexit( _cleanup_winsock ); - _winsock_init = 1; - } -} - -int socket_loopback_client(int port, int type) -{ - FH f = _fh_alloc( &_fh_socket_class ); - struct sockaddr_in addr; - SOCKET s; - - if (!f) - return -1; - - if (!_winsock_init) - _init_winsock(); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket(AF_INET, type, 0); - if(s == INVALID_SOCKET) { - D("socket_loopback_client: could not create socket\n" ); - _fh_close(f); - return -1; - } - - f->fh_socket = s; - if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port ); - _fh_close(f); - return -1; - } - snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); - D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); - return _fh_to_int(f); -} - -#define LISTEN_BACKLOG 4 - -int socket_loopback_server(int port, int type) -{ - FH f = _fh_alloc( &_fh_socket_class ); - struct sockaddr_in addr; - SOCKET s; - int n; - - if (!f) { - return -1; - } - - if (!_winsock_init) - _init_winsock(); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket(AF_INET, type, 0); - if(s == INVALID_SOCKET) return -1; - - f->fh_socket = s; - - n = 1; - setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n)); - - if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - _fh_close(f); - return -1; - } - if (type == SOCK_STREAM) { - int ret; - - ret = listen(s, LISTEN_BACKLOG); - if (ret < 0) { - _fh_close(f); - return -1; - } - } - snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); - D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); - return _fh_to_int(f); -} - - -int socket_network_client(const char *host, int port, int type) -{ - FH f = _fh_alloc( &_fh_socket_class ); - struct hostent *hp; - struct sockaddr_in addr; - SOCKET s; - - if (!f) - return -1; - - if (!_winsock_init) - _init_winsock(); - - hp = gethostbyname(host); - if(hp == 0) { - _fh_close(f); - return -1; - } - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = hp->h_addrtype; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); - - s = socket(hp->h_addrtype, type, 0); - if(s == INVALID_SOCKET) { - _fh_close(f); - return -1; - } - f->fh_socket = s; - - if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - _fh_close(f); - return -1; - } - - snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); - D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); - return _fh_to_int(f); -} - - -int socket_inaddr_any_server(int port, int type) -{ - FH f = _fh_alloc( &_fh_socket_class ); - struct sockaddr_in addr; - SOCKET s; - int n; - - if (!f) - return -1; - - if (!_winsock_init) - _init_winsock(); - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - s = socket(AF_INET, type, 0); - if(s == INVALID_SOCKET) { - _fh_close(f); - return -1; - } - - f->fh_socket = s; - n = 1; - setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n)); - - if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - _fh_close(f); - return -1; - } - - if (type == SOCK_STREAM) { - int ret; - - ret = listen(s, LISTEN_BACKLOG); - if (ret < 0) { - _fh_close(f); - return -1; - } - } - snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port ); - D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) ); - return _fh_to_int(f); -} - -#undef accept -int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) -{ - FH serverfh = _fh_from_int(serverfd); - FH fh; - - if ( !serverfh || serverfh->clazz != &_fh_socket_class ) { - D( "adb_socket_accept: invalid fd %d\n", serverfd ); - return -1; - } - - fh = _fh_alloc( &_fh_socket_class ); - if (!fh) { - D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" ); - return -1; - } - - fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen ); - if (fh->fh_socket == INVALID_SOCKET) { - _fh_close( fh ); - D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() ); - return -1; - } - - snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name ); - D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) ); - return _fh_to_int(fh); -} - - -void disable_tcp_nagle(int fd) -{ - FH fh = _fh_from_int(fd); - int on; - - if ( !fh || fh->clazz != &_fh_socket_class ) - return; - - setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) ); -} - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** emulated socketpairs *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -/* we implement socketpairs directly in use space for the following reasons: - * - it avoids copying data from/to the Nt kernel - * - it allows us to implement fdevent hooks easily and cheaply, something - * that is not possible with standard Win32 pipes !! - * - * basically, we use two circular buffers, each one corresponding to a given - * direction. - * - * each buffer is implemented as two regions: - * - * region A which is (a_start,a_end) - * region B which is (0, b_end) with b_end <= a_start - * - * an empty buffer has: a_start = a_end = b_end = 0 - * - * a_start is the pointer where we start reading data - * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE, - * then you start writing at b_end - * - * the buffer is full when b_end == a_start && a_end == BUFFER_SIZE - * - * there is room when b_end < a_start || a_end < BUFER_SIZE - * - * when reading, a_start is incremented, it a_start meets a_end, then - * we do: a_start = 0, a_end = b_end, b_end = 0, and keep going on.. - */ - -#define BIP_BUFFER_SIZE 4096 - -#if 0 -#include <stdio.h> -# define BIPD(x) D x -# define BIPDUMP bip_dump_hex - -static void bip_dump_hex( const unsigned char* ptr, size_t len ) -{ - int nn, len2 = len; - - if (len2 > 8) len2 = 8; - - for (nn = 0; nn < len2; nn++) - printf("%02x", ptr[nn]); - printf(" "); - - for (nn = 0; nn < len2; nn++) { - int c = ptr[nn]; - if (c < 32 || c > 127) - c = '.'; - printf("%c", c); - } - printf("\n"); - fflush(stdout); -} - -#else -# define BIPD(x) do {} while (0) -# define BIPDUMP(p,l) BIPD(p) -#endif - -typedef struct BipBufferRec_ -{ - int a_start; - int a_end; - int b_end; - int fdin; - int fdout; - int closed; - int can_write; /* boolean */ - HANDLE evt_write; /* event signaled when one can write to a buffer */ - int can_read; /* boolean */ - HANDLE evt_read; /* event signaled when one can read from a buffer */ - CRITICAL_SECTION lock; - unsigned char buff[ BIP_BUFFER_SIZE ]; - -} BipBufferRec, *BipBuffer; - -static void -bip_buffer_init( BipBuffer buffer ) -{ - D( "bit_buffer_init %p\n", buffer ); - buffer->a_start = 0; - buffer->a_end = 0; - buffer->b_end = 0; - buffer->can_write = 1; - buffer->can_read = 0; - buffer->fdin = 0; - buffer->fdout = 0; - buffer->closed = 0; - buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL ); - buffer->evt_read = CreateEvent( NULL, TRUE, FALSE, NULL ); - InitializeCriticalSection( &buffer->lock ); -} - -static void -bip_buffer_close( BipBuffer bip ) -{ - bip->closed = 1; - - if (!bip->can_read) { - SetEvent( bip->evt_read ); - } - if (!bip->can_write) { - SetEvent( bip->evt_write ); - } -} - -static void -bip_buffer_done( BipBuffer bip ) -{ - BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout )); - CloseHandle( bip->evt_read ); - CloseHandle( bip->evt_write ); - DeleteCriticalSection( &bip->lock ); -} - -static int -bip_buffer_write( BipBuffer bip, const void* src, int len ) -{ - int avail, count = 0; - - if (len <= 0) - return 0; - - BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len )); - BIPDUMP( src, len ); - - EnterCriticalSection( &bip->lock ); - - while (!bip->can_write) { - int ret; - LeaveCriticalSection( &bip->lock ); - - if (bip->closed) { - errno = EPIPE; - return -1; - } - /* spinlocking here is probably unfair, but let's live with it */ - ret = WaitForSingleObject( bip->evt_write, INFINITE ); - if (ret != WAIT_OBJECT_0) { /* buffer probably closed */ - D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() ); - return 0; - } - if (bip->closed) { - errno = EPIPE; - return -1; - } - EnterCriticalSection( &bip->lock ); - } - - BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len )); - - avail = BIP_BUFFER_SIZE - bip->a_end; - if (avail > 0) - { - /* we can append to region A */ - if (avail > len) - avail = len; - - memcpy( bip->buff + bip->a_end, src, avail ); - src += avail; - count += avail; - len -= avail; - - bip->a_end += avail; - if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) { - bip->can_write = 0; - ResetEvent( bip->evt_write ); - goto Exit; - } - } - - if (len == 0) - goto Exit; - - avail = bip->a_start - bip->b_end; - assert( avail > 0 ); /* since can_write is TRUE */ - - if (avail > len) - avail = len; - - memcpy( bip->buff + bip->b_end, src, avail ); - count += avail; - bip->b_end += avail; - - if (bip->b_end == bip->a_start) { - bip->can_write = 0; - ResetEvent( bip->evt_write ); - } - -Exit: - assert( count > 0 ); - - if ( !bip->can_read ) { - bip->can_read = 1; - SetEvent( bip->evt_read ); - } - - BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", - bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read )); - LeaveCriticalSection( &bip->lock ); - - return count; - } - -static int -bip_buffer_read( BipBuffer bip, void* dst, int len ) -{ - int avail, count = 0; - - if (len <= 0) - return 0; - - BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len )); - - EnterCriticalSection( &bip->lock ); - while ( !bip->can_read ) - { -#if 0 - LeaveCriticalSection( &bip->lock ); - errno = EAGAIN; - return -1; -#else - int ret; - LeaveCriticalSection( &bip->lock ); - - if (bip->closed) { - errno = EPIPE; - return -1; - } - - ret = WaitForSingleObject( bip->evt_read, INFINITE ); - if (ret != WAIT_OBJECT_0) { /* probably closed buffer */ - D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError()); - return 0; - } - if (bip->closed) { - errno = EPIPE; - return -1; - } - EnterCriticalSection( &bip->lock ); -#endif - } - - BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len )); - - avail = bip->a_end - bip->a_start; - assert( avail > 0 ); /* since can_read is TRUE */ - - if (avail > len) - avail = len; - - memcpy( dst, bip->buff + bip->a_start, avail ); - dst += avail; - count += avail; - len -= avail; - - bip->a_start += avail; - if (bip->a_start < bip->a_end) - goto Exit; - - bip->a_start = 0; - bip->a_end = bip->b_end; - bip->b_end = 0; - - avail = bip->a_end; - if (avail > 0) { - if (avail > len) - avail = len; - memcpy( dst, bip->buff, avail ); - count += avail; - bip->a_start += avail; - - if ( bip->a_start < bip->a_end ) - goto Exit; - - bip->a_start = bip->a_end = 0; - } - - bip->can_read = 0; - ResetEvent( bip->evt_read ); - -Exit: - assert( count > 0 ); - - if (!bip->can_write ) { - bip->can_write = 1; - SetEvent( bip->evt_write ); - } - - BIPDUMP( (const unsigned char*)dst - count, count ); - BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n", - bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read )); - LeaveCriticalSection( &bip->lock ); - - return count; -} - -typedef struct SocketPairRec_ -{ - BipBufferRec a2b_bip; - BipBufferRec b2a_bip; - FH a_fd; - int used; - -} SocketPairRec; - -void _fh_socketpair_init( FH f ) -{ - f->fh_pair = NULL; -} - -static int -_fh_socketpair_close( FH f ) -{ - if ( f->fh_pair ) { - SocketPair pair = f->fh_pair; - - if ( f == pair->a_fd ) { - pair->a_fd = NULL; - } - - bip_buffer_close( &pair->b2a_bip ); - bip_buffer_close( &pair->a2b_bip ); - - if ( --pair->used == 0 ) { - bip_buffer_done( &pair->b2a_bip ); - bip_buffer_done( &pair->a2b_bip ); - free( pair ); - } - f->fh_pair = NULL; - } - return 0; -} - -static int -_fh_socketpair_lseek( FH f, int pos, int origin ) -{ - errno = ESPIPE; - return -1; -} - -static int -_fh_socketpair_read( FH f, void* buf, int len ) -{ - SocketPair pair = f->fh_pair; - BipBuffer bip; - - if (!pair) - return -1; - - if ( f == pair->a_fd ) - bip = &pair->b2a_bip; - else - bip = &pair->a2b_bip; - - return bip_buffer_read( bip, buf, len ); -} - -static int -_fh_socketpair_write( FH f, const void* buf, int len ) -{ - SocketPair pair = f->fh_pair; - BipBuffer bip; - - if (!pair) - return -1; - - if ( f == pair->a_fd ) - bip = &pair->a2b_bip; - else - bip = &pair->b2a_bip; - - return bip_buffer_write( bip, buf, len ); -} - - -static void _fh_socketpair_hook( FH f, int event, EventHook hook ); /* forward */ - -static const FHClassRec _fh_socketpair_class = -{ - _fh_socketpair_init, - _fh_socketpair_close, - _fh_socketpair_lseek, - _fh_socketpair_read, - _fh_socketpair_write, - _fh_socketpair_hook -}; - - -int adb_socketpair( int sv[2] ) -{ - FH fa, fb; - SocketPair pair; - - fa = _fh_alloc( &_fh_socketpair_class ); - fb = _fh_alloc( &_fh_socketpair_class ); - - if (!fa || !fb) - goto Fail; - - pair = malloc( sizeof(*pair) ); - if (pair == NULL) { - D("adb_socketpair: not enough memory to allocate pipes\n" ); - goto Fail; - } - - bip_buffer_init( &pair->a2b_bip ); - bip_buffer_init( &pair->b2a_bip ); - - fa->fh_pair = pair; - fb->fh_pair = pair; - pair->used = 2; - pair->a_fd = fa; - - sv[0] = _fh_to_int(fa); - sv[1] = _fh_to_int(fb); - - pair->a2b_bip.fdin = sv[0]; - pair->a2b_bip.fdout = sv[1]; - pair->b2a_bip.fdin = sv[1]; - pair->b2a_bip.fdout = sv[0]; - - snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] ); - snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] ); - D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] ); - return 0; - -Fail: - _fh_close(fb); - _fh_close(fa); - return -1; -} - -/**************************************************************************/ -/**************************************************************************/ -/***** *****/ -/***** fdevents emulation *****/ -/***** *****/ -/***** this is a very simple implementation, we rely on the fact *****/ -/***** that ADB doesn't use FDE_ERROR. *****/ -/***** *****/ -/**************************************************************************/ -/**************************************************************************/ - -#define FATAL(x...) fatal(__FUNCTION__, x) - -#if DEBUG -static void dump_fde(fdevent *fde, const char *info) -{ - fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, - fde->state & FDE_READ ? 'R' : ' ', - fde->state & FDE_WRITE ? 'W' : ' ', - fde->state & FDE_ERROR ? 'E' : ' ', - info); -} -#else -#define dump_fde(fde, info) do { } while(0) -#endif - -#define FDE_EVENTMASK 0x00ff -#define FDE_STATEMASK 0xff00 - -#define FDE_ACTIVE 0x0100 -#define FDE_PENDING 0x0200 -#define FDE_CREATED 0x0400 - -static void fdevent_plist_enqueue(fdevent *node); -static void fdevent_plist_remove(fdevent *node); -static fdevent *fdevent_plist_dequeue(void); - -static fdevent list_pending = { - .next = &list_pending, - .prev = &list_pending, -}; - -static fdevent **fd_table = 0; -static int fd_table_max = 0; - -typedef struct EventLooperRec_* EventLooper; - -typedef struct EventHookRec_ -{ - EventHook next; - FH fh; - HANDLE h; - int wanted; /* wanted event flags */ - int ready; /* ready event flags */ - void* aux; - void (*prepare)( EventHook hook ); - int (*start) ( EventHook hook ); - void (*stop) ( EventHook hook ); - int (*check) ( EventHook hook ); - int (*peek) ( EventHook hook ); -} EventHookRec; - -static EventHook _free_hooks; - -static EventHook -event_hook_alloc( FH fh ) -{ - EventHook hook = _free_hooks; - if (hook != NULL) - _free_hooks = hook->next; - else { - hook = malloc( sizeof(*hook) ); - if (hook == NULL) - fatal( "could not allocate event hook\n" ); - } - hook->next = NULL; - hook->fh = fh; - hook->wanted = 0; - hook->ready = 0; - hook->h = INVALID_HANDLE_VALUE; - hook->aux = NULL; - - hook->prepare = NULL; - hook->start = NULL; - hook->stop = NULL; - hook->check = NULL; - hook->peek = NULL; - - return hook; -} - -static void -event_hook_free( EventHook hook ) -{ - hook->fh = NULL; - hook->wanted = 0; - hook->ready = 0; - hook->next = _free_hooks; - _free_hooks = hook; -} - - -static void -event_hook_signal( EventHook hook ) -{ - FH f = hook->fh; - int fd = _fh_to_int(f); - fdevent* fde = fd_table[ fd - WIN32_FH_BASE ]; - - if (fde != NULL && fde->fd == fd) { - if ((fde->state & FDE_PENDING) == 0) { - fde->state |= FDE_PENDING; - fdevent_plist_enqueue( fde ); - } - fde->events |= hook->wanted; - } -} - - -#define MAX_LOOPER_HANDLES WIN32_MAX_FHS - -typedef struct EventLooperRec_ -{ - EventHook hooks; - HANDLE htab[ MAX_LOOPER_HANDLES ]; - int htab_count; - -} EventLooperRec; - -static EventHook* -event_looper_find_p( EventLooper looper, FH fh ) -{ - EventHook *pnode = &looper->hooks; - EventHook node = *pnode; - for (;;) { - if ( node == NULL || node->fh == fh ) - break; - pnode = &node->next; - node = *pnode; - } - return pnode; -} - -static void -event_looper_hook( EventLooper looper, int fd, int events ) -{ - FH f = _fh_from_int(fd); - EventHook *pnode; - EventHook node; - - if (f == NULL) /* invalid arg */ { - D("event_looper_hook: invalid fd=%d\n", fd); - return; - } - - pnode = event_looper_find_p( looper, f ); - node = *pnode; - if ( node == NULL ) { - node = event_hook_alloc( f ); - node->next = *pnode; - *pnode = node; - } - - if ( (node->wanted & events) != events ) { - /* this should update start/stop/check/peek */ - D("event_looper_hook: call hook for %d (new=%x, old=%x)\n", - fd, node->wanted, events); - f->clazz->_fh_hook( f, events & ~node->wanted, node ); - node->wanted |= events; - } else { - D("event_looper_hook: ignoring events %x for %d wanted=%x)\n", - events, fd, node->wanted); - } -} - -static void -event_looper_unhook( EventLooper looper, int fd, int events ) -{ - FH fh = _fh_from_int(fd); - EventHook *pnode = event_looper_find_p( looper, fh ); - EventHook node = *pnode; - - if (node != NULL) { - int events2 = events & node->wanted; - if ( events2 == 0 ) { - D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd ); - return; - } - node->wanted &= ~events2; - if (!node->wanted) { - *pnode = node->next; - event_hook_free( node ); - } - } -} - -static EventLooperRec win32_looper; - -static void fdevent_init(void) -{ - win32_looper.htab_count = 0; - win32_looper.hooks = NULL; -} - -static void fdevent_connect(fdevent *fde) -{ - EventLooper looper = &win32_looper; - int events = fde->state & FDE_EVENTMASK; - - if (events != 0) - event_looper_hook( looper, fde->fd, events ); -} - -static void fdevent_disconnect(fdevent *fde) -{ - EventLooper looper = &win32_looper; - int events = fde->state & FDE_EVENTMASK; - - if (events != 0) - event_looper_unhook( looper, fde->fd, events ); -} - -static void fdevent_update(fdevent *fde, unsigned events) -{ - EventLooper looper = &win32_looper; - unsigned events0 = fde->state & FDE_EVENTMASK; - - if (events != events0) { - int removes = events0 & ~events; - int adds = events & ~events0; - if (removes) { - D("fdevent_update: remove %x from %d\n", removes, fde->fd); - event_looper_unhook( looper, fde->fd, removes ); - } - if (adds) { - D("fdevent_update: add %x to %d\n", adds, fde->fd); - event_looper_hook ( looper, fde->fd, adds ); - } - } -} - -static void fdevent_process() -{ - EventLooper looper = &win32_looper; - EventHook hook; - int gotone = 0; - - /* if we have at least one ready hook, execute it/them */ - for (hook = looper->hooks; hook; hook = hook->next) { - hook->ready = 0; - if (hook->prepare) { - hook->prepare(hook); - if (hook->ready != 0) { - event_hook_signal( hook ); - gotone = 1; - } - } - } - - /* nothing's ready yet, so wait for something to happen */ - if (!gotone) - { - looper->htab_count = 0; - - for (hook = looper->hooks; hook; hook = hook->next) - { - if (hook->start && !hook->start(hook)) { - D( "fdevent_process: error when starting a hook\n" ); - return; - } - if (hook->h != INVALID_HANDLE_VALUE) { - int nn; - - for (nn = 0; nn < looper->htab_count; nn++) - { - if ( looper->htab[nn] == hook->h ) - goto DontAdd; - } - looper->htab[ looper->htab_count++ ] = hook->h; - DontAdd: - ; - } - } - - if (looper->htab_count == 0) { - D( "fdevent_process: nothing to wait for !!\n" ); - return; - } - - do - { - int wait_ret; - - D( "adb_win32: waiting for %d events\n", looper->htab_count ); - if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) { - D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS, aborting!\n", looper->htab_count); - abort(); - } - wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE ); - if (wait_ret == (int)WAIT_FAILED) { - D( "adb_win32: wait failed, error %ld\n", GetLastError() ); - } else { - D( "adb_win32: got one (index %d)\n", wait_ret ); - - /* according to Cygwin, some objects like consoles wake up on "inappropriate" events - * like mouse movements. we need to filter these with the "check" function - */ - if ((unsigned)wait_ret < (unsigned)looper->htab_count) - { - for (hook = looper->hooks; hook; hook = hook->next) - { - if ( looper->htab[wait_ret] == hook->h && - (!hook->check || hook->check(hook)) ) - { - D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready ); - event_hook_signal( hook ); - gotone = 1; - break; - } - } - } - } - } - while (!gotone); - - for (hook = looper->hooks; hook; hook = hook->next) { - if (hook->stop) - hook->stop( hook ); - } - } - - for (hook = looper->hooks; hook; hook = hook->next) { - if (hook->peek && hook->peek(hook)) - event_hook_signal( hook ); - } -} - - -static void fdevent_register(fdevent *fde) -{ - int fd = fde->fd - WIN32_FH_BASE; - - if(fd < 0) { - FATAL("bogus negative fd (%d)\n", fde->fd); - } - - if(fd >= fd_table_max) { - int oldmax = fd_table_max; - if(fde->fd > 32000) { - FATAL("bogus huuuuge fd (%d)\n", fde->fd); - } - if(fd_table_max == 0) { - fdevent_init(); - fd_table_max = 256; - } - while(fd_table_max <= fd) { - fd_table_max *= 2; - } - fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max); - if(fd_table == 0) { - FATAL("could not expand fd_table to %d entries\n", fd_table_max); - } - memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); - } - - fd_table[fd] = fde; -} - -static void fdevent_unregister(fdevent *fde) -{ - int fd = fde->fd - WIN32_FH_BASE; - - if((fd < 0) || (fd >= fd_table_max)) { - FATAL("fd out of range (%d)\n", fde->fd); - } - - if(fd_table[fd] != fde) { - FATAL("fd_table out of sync"); - } - - fd_table[fd] = 0; - - if(!(fde->state & FDE_DONT_CLOSE)) { - dump_fde(fde, "close"); - adb_close(fde->fd); - } -} - -static void fdevent_plist_enqueue(fdevent *node) -{ - fdevent *list = &list_pending; - - node->next = list; - node->prev = list->prev; - node->prev->next = node; - list->prev = node; -} - -static void fdevent_plist_remove(fdevent *node) -{ - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; -} - -static fdevent *fdevent_plist_dequeue(void) -{ - fdevent *list = &list_pending; - fdevent *node = list->next; - - if(node == list) return 0; - - list->next = node->next; - list->next->prev = list; - node->next = 0; - node->prev = 0; - - return node; -} - -fdevent *fdevent_create(int fd, fd_func func, void *arg) -{ - fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); - if(fde == 0) return 0; - fdevent_install(fde, fd, func, arg); - fde->state |= FDE_CREATED; - return fde; -} - -void fdevent_destroy(fdevent *fde) -{ - if(fde == 0) return; - if(!(fde->state & FDE_CREATED)) { - FATAL("fde %p not created by fdevent_create()\n", fde); - } - fdevent_remove(fde); -} - -void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) -{ - memset(fde, 0, sizeof(fdevent)); - fde->state = FDE_ACTIVE; - fde->fd = fd; - fde->func = func; - fde->arg = arg; - - fdevent_register(fde); - dump_fde(fde, "connect"); - fdevent_connect(fde); - fde->state |= FDE_ACTIVE; -} - -void fdevent_remove(fdevent *fde) -{ - if(fde->state & FDE_PENDING) { - fdevent_plist_remove(fde); - } - - if(fde->state & FDE_ACTIVE) { - fdevent_disconnect(fde); - dump_fde(fde, "disconnect"); - fdevent_unregister(fde); - } - - fde->state = 0; - fde->events = 0; -} - - -void fdevent_set(fdevent *fde, unsigned events) -{ - events &= FDE_EVENTMASK; - - if((fde->state & FDE_EVENTMASK) == (int)events) return; - - if(fde->state & FDE_ACTIVE) { - fdevent_update(fde, events); - dump_fde(fde, "update"); - } - - fde->state = (fde->state & FDE_STATEMASK) | events; - - if(fde->state & FDE_PENDING) { - /* if we're pending, make sure - ** we don't signal an event that - ** is no longer wanted. - */ - fde->events &= (~events); - if(fde->events == 0) { - fdevent_plist_remove(fde); - fde->state &= (~FDE_PENDING); - } - } -} - -void fdevent_add(fdevent *fde, unsigned events) -{ - fdevent_set( - fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); -} - -void fdevent_del(fdevent *fde, unsigned events) -{ - fdevent_set( - fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); -} - -void fdevent_loop() -{ - fdevent *fde; - - for(;;) { -#if DEBUG - fprintf(stderr,"--- ---- waiting for events\n"); -#endif - fdevent_process(); - - while((fde = fdevent_plist_dequeue())) { - unsigned events = fde->events; - fde->events = 0; - fde->state &= (~FDE_PENDING); - dump_fde(fde, "callback"); - fde->func(fde->fd, events, fde->arg); - } - } -} - -/** FILE EVENT HOOKS - **/ - -static void _event_file_prepare( EventHook hook ) -{ - if (hook->wanted & (FDE_READ|FDE_WRITE)) { - /* we can always read/write */ - hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE); - } -} - -static int _event_file_peek( EventHook hook ) -{ - return (hook->wanted & (FDE_READ|FDE_WRITE)); -} - -static void _fh_file_hook( FH f, int events, EventHook hook ) -{ - hook->h = f->fh_handle; - hook->prepare = _event_file_prepare; - hook->peek = _event_file_peek; -} - -/** SOCKET EVENT HOOKS - **/ - -static void _event_socket_verify( EventHook hook, WSANETWORKEVENTS* evts ) -{ - if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) { - if (hook->wanted & FDE_READ) - hook->ready |= FDE_READ; - if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR) - hook->ready |= FDE_ERROR; - } - if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) { - if (hook->wanted & FDE_WRITE) - hook->ready |= FDE_WRITE; - if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR) - hook->ready |= FDE_ERROR; - } - if ( evts->lNetworkEvents & FD_OOB ) { - if (hook->wanted & FDE_ERROR) - hook->ready |= FDE_ERROR; - } -} - -static void _event_socket_prepare( EventHook hook ) -{ - WSANETWORKEVENTS evts; - - /* look if some of the events we want already happened ? */ - if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts )) - _event_socket_verify( hook, &evts ); -} - -static int _socket_wanted_to_flags( int wanted ) -{ - int flags = 0; - if (wanted & FDE_READ) - flags |= FD_READ | FD_ACCEPT | FD_CLOSE; - - if (wanted & FDE_WRITE) - flags |= FD_WRITE | FD_CONNECT | FD_CLOSE; - - if (wanted & FDE_ERROR) - flags |= FD_OOB; - - return flags; -} - -static int _event_socket_start( EventHook hook ) -{ - /* create an event which we're going to wait for */ - FH fh = hook->fh; - long flags = _socket_wanted_to_flags( hook->wanted ); - - hook->h = fh->event; - if (hook->h == INVALID_HANDLE_VALUE) { - D( "_event_socket_start: no event for %s\n", fh->name ); - return 0; - } - - if ( flags != fh->mask ) { - D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags ); - if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) { - D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() ); - CloseHandle( hook->h ); - hook->h = INVALID_HANDLE_VALUE; - exit(1); - return 0; - } - fh->mask = flags; - } - return 1; -} - -static void _event_socket_stop( EventHook hook ) -{ - hook->h = INVALID_HANDLE_VALUE; -} - -static int _event_socket_check( EventHook hook ) -{ - int result = 0; - FH fh = hook->fh; - WSANETWORKEVENTS evts; - - if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) { - _event_socket_verify( hook, &evts ); - result = (hook->ready != 0); - if (result) { - ResetEvent( hook->h ); - } - } - D( "_event_socket_check %s returns %d\n", fh->name, result ); - return result; -} - -static int _event_socket_peek( EventHook hook ) -{ - WSANETWORKEVENTS evts; - FH fh = hook->fh; - - /* look if some of the events we want already happened ? */ - if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) { - _event_socket_verify( hook, &evts ); - if (hook->ready) - ResetEvent( hook->h ); - } - - return hook->ready != 0; -} - - - -static void _fh_socket_hook( FH f, int events, EventHook hook ) -{ - hook->prepare = _event_socket_prepare; - hook->start = _event_socket_start; - hook->stop = _event_socket_stop; - hook->check = _event_socket_check; - hook->peek = _event_socket_peek; - - _event_socket_start( hook ); -} - -/** SOCKETPAIR EVENT HOOKS - **/ - -static void _event_socketpair_prepare( EventHook hook ) -{ - FH fh = hook->fh; - SocketPair pair = fh->fh_pair; - BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip; - BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip; - - if (hook->wanted & FDE_READ && rbip->can_read) - hook->ready |= FDE_READ; - - if (hook->wanted & FDE_WRITE && wbip->can_write) - hook->ready |= FDE_WRITE; - } - - static int _event_socketpair_start( EventHook hook ) - { - FH fh = hook->fh; - SocketPair pair = fh->fh_pair; - BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip; - BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip; - - if (hook->wanted == FDE_READ) - hook->h = rbip->evt_read; - - else if (hook->wanted == FDE_WRITE) - hook->h = wbip->evt_write; - - else { - D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" ); - return 0; - } - D( "_event_socketpair_start: hook %s for %x wanted=%x\n", - hook->fh->name, _fh_to_int(fh), hook->wanted); - return 1; -} - -static int _event_socketpair_peek( EventHook hook ) -{ - _event_socketpair_prepare( hook ); - return hook->ready != 0; -} - -static void _fh_socketpair_hook( FH fh, int events, EventHook hook ) -{ - hook->prepare = _event_socketpair_prepare; - hook->start = _event_socketpair_start; - hook->peek = _event_socketpair_peek; -} - - -void -adb_sysdeps_init( void ) -{ -#define ADB_MUTEX(x) InitializeCriticalSection( & x ); -#include "mutex_list.h" - InitializeCriticalSection( &_win32_lock ); -} - diff --git a/adb/test_track_devices.c b/adb/test_track_devices.c deleted file mode 100644 index 77b3ad994e44929b2dfd7d47deb674651bbf46a0..0000000000000000000000000000000000000000 --- a/adb/test_track_devices.c +++ /dev/null @@ -1,97 +0,0 @@ -/* a simple test program, connects to ADB server, and opens a track-devices session */ -#include <netdb.h> -#include <sys/socket.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <memory.h> - -static void -panic( const char* msg ) -{ - fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno)); - exit(1); -} - -static int -unix_write( int fd, const char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = write(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - -static int -unix_read( int fd, char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = read(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - - -int main( void ) -{ - int ret, s; - struct sockaddr_in server; - char buffer[1024]; - const char* request = "host:track-devices"; - int len; - - memset( &server, 0, sizeof(server) ); - server.sin_family = AF_INET; - server.sin_port = htons(5037); - server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket( PF_INET, SOCK_STREAM, 0 ); - ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); - if (ret < 0) panic( "could not connect to server" ); - - /* send the request */ - len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); - if (unix_write(s, buffer, len) < 0) - panic( "could not send request" ); - - /* read the OKAY answer */ - if (unix_read(s, buffer, 4) != 4) - panic( "could not read request" ); - - printf( "server answer: %.*s\n", 4, buffer ); - - /* now loop */ - for (;;) { - char head[5] = "0000"; - - if (unix_read(s, head, 4) < 0) - panic("could not read length"); - - if ( sscanf( head, "%04x", &len ) != 1 ) - panic("could not decode length"); - - if (unix_read(s, buffer, len) != len) - panic("could not read data"); - - printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); - } - close(s); -} diff --git a/adb/test_track_jdwp.c b/adb/test_track_jdwp.c deleted file mode 100644 index 8ecc6b87af597f8e4103f76e34f37ce8f7463125..0000000000000000000000000000000000000000 --- a/adb/test_track_jdwp.c +++ /dev/null @@ -1,97 +0,0 @@ -/* a simple test program, connects to ADB server, and opens a track-devices session */ -#include <netdb.h> -#include <sys/socket.h> -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <memory.h> - -static void -panic( const char* msg ) -{ - fprintf(stderr, "PANIC: %s: %s\n", msg, strerror(errno)); - exit(1); -} - -static int -unix_write( int fd, const char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = write(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - -static int -unix_read( int fd, char* buf, int len ) -{ - int result = 0; - while (len > 0) { - int len2 = read(fd, buf, len); - if (len2 < 0) { - if (errno == EINTR || errno == EAGAIN) - continue; - return -1; - } - result += len2; - len -= len2; - buf += len2; - } - return result; -} - - -int main( void ) -{ - int ret, s; - struct sockaddr_in server; - char buffer[1024]; - const char* request = "track-jdwp"; - int len; - - memset( &server, 0, sizeof(server) ); - server.sin_family = AF_INET; - server.sin_port = htons(5037); - server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket( PF_INET, SOCK_STREAM, 0 ); - ret = connect( s, (struct sockaddr*) &server, sizeof(server) ); - if (ret < 0) panic( "could not connect to server" ); - - /* send the request */ - len = snprintf( buffer, sizeof buffer, "%04x%s", strlen(request), request ); - if (unix_write(s, buffer, len) < 0) - panic( "could not send request" ); - - /* read the OKAY answer */ - if (unix_read(s, buffer, 4) != 4) - panic( "could not read request" ); - - printf( "server answer: %.*s\n", 4, buffer ); - - /* now loop */ - for (;;) { - char head[5] = "0000"; - - if (unix_read(s, head, 4) < 0) - panic("could not read length"); - - if ( sscanf( head, "%04x", &len ) != 1 ) - panic("could not decode length"); - - if (unix_read(s, buffer, len) != len) - panic("could not read data"); - - printf( "received header %.*s (%d bytes):\n%.*s", 4, head, len, len, buffer ); - } - close(s); -} diff --git a/adb/transport.c b/adb/transport.c deleted file mode 100644 index c76f1a5f8f4a5c73a7948a79af835258f8c8ab5b..0000000000000000000000000000000000000000 --- a/adb/transport.c +++ /dev/null @@ -1,958 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_TRANSPORT -#include "adb.h" - -static void transport_unref(atransport *t); - -static atransport transport_list = { - .next = &transport_list, - .prev = &transport_list, -}; - -ADB_MUTEX_DEFINE( transport_lock ); - -#if ADB_TRACE -static void dump_hex( const unsigned char* ptr, size_t len ) -{ - int nn, len2 = len; - - if (len2 > 16) len2 = 16; - - for (nn = 0; nn < len2; nn++) - D("%02x", ptr[nn]); - D(" "); - - for (nn = 0; nn < len2; nn++) { - int c = ptr[nn]; - if (c < 32 || c > 127) - c = '.'; - D("%c", c); - } - D("\n"); - fflush(stdout); -} -#endif - -void -kick_transport(atransport* t) -{ - if (t && !t->kicked) - { - int kicked; - - adb_mutex_lock(&transport_lock); - kicked = t->kicked; - if (!kicked) - t->kicked = 1; - adb_mutex_unlock(&transport_lock); - - if (!kicked) - t->kick(t); - } -} - -void -run_transport_disconnects(atransport* t) -{ - adisconnect* dis = t->disconnects.next; - - D("run_transport_disconnects: %p (%s)\n", t, t->serial ? t->serial : "unknown" ); - while (dis != &t->disconnects) { - adisconnect* next = dis->next; - dis->func( dis->opaque, t ); - dis = next; - } -} - -static int -read_packet(int fd, apacket** ppacket) -{ - char *p = (char*)ppacket; /* really read a packet address */ - int r; - int len = sizeof(*ppacket); - while(len > 0) { - r = adb_read(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - D("read_packet: %d error %d %d\n", fd, r, errno); - if((r < 0) && (errno == EINTR)) continue; - return -1; - } - } - -#if ADB_TRACE - if (ADB_TRACING) - { - unsigned command = (*ppacket)->msg.command; - int len = (*ppacket)->msg.data_length; - char cmd[5]; - int n; - - for (n = 0; n < 4; n++) { - int b = (command >> (n*8)) & 255; - if (b >= 32 && b < 127) - cmd[n] = (char)b; - else - cmd[n] = '.'; - } - cmd[4] = 0; - - D("read_packet: %d ok: [%08x %s] %08x %08x (%d) ", - fd, command, cmd, (*ppacket)->msg.arg0, (*ppacket)->msg.arg1, len); - dump_hex((*ppacket)->data, len); - } -#endif - return 0; -} - -static int -write_packet(int fd, apacket** ppacket) -{ - char *p = (char*) ppacket; /* we really write the packet address */ - int r, len = sizeof(ppacket); - -#if ADB_TRACE - if (ADB_TRACING) - { - unsigned command = (*ppacket)->msg.command; - int len = (*ppacket)->msg.data_length; - char cmd[5]; - int n; - - for (n = 0; n < 4; n++) { - int b = (command >> (n*8)) & 255; - if (b >= 32 && b < 127) - cmd[n] = (char)b; - else - cmd[n] = '.'; - } - cmd[4] = 0; - - D("write_packet: %d [%08x %s] %08x %08x (%d) ", - fd, command, cmd, (*ppacket)->msg.arg0, (*ppacket)->msg.arg1, len); - dump_hex((*ppacket)->data, len); - } -#endif - len = sizeof(ppacket); - while(len > 0) { - r = adb_write(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - D("write_packet: %d error %d %d\n", fd, r, errno); - if((r < 0) && (errno == EINTR)) continue; - return -1; - } - } - return 0; -} - -static void transport_socket_events(int fd, unsigned events, void *_t) -{ - if(events & FDE_READ){ - apacket *p = 0; - if(read_packet(fd, &p)){ - D("failed to read packet from transport socket on fd %d\n", fd); - } else { - handle_packet(p, (atransport *) _t); - } - } -} - -void send_packet(apacket *p, atransport *t) -{ - unsigned char *x; - unsigned sum; - unsigned count; - - p->msg.magic = p->msg.command ^ 0xffffffff; - - count = p->msg.data_length; - x = (unsigned char *) p->data; - sum = 0; - while(count-- > 0){ - sum += *x++; - } - p->msg.data_check = sum; - - print_packet("send", p); - - if (t == NULL) { - fatal_errno("Transport is null"); - D("Transport is null \n"); - } - - if(write_packet(t->transport_socket, &p)){ - fatal_errno("cannot enqueue packet on transport socket"); - } -} - -/* The transport is opened by transport_register_func before -** the input and output threads are started. -** -** The output thread issues a SYNC(1, token) message to let -** the input thread know to start things up. In the event -** of transport IO failure, the output thread will post a -** SYNC(0,0) message to ensure shutdown. -** -** The transport will not actually be closed until both -** threads exit, but the input thread will kick the transport -** on its way out to disconnect the underlying device. -*/ - -static void *output_thread(void *_t) -{ - atransport *t = _t; - apacket *p; - - D("from_remote: starting thread for transport %p, on fd %d\n", t, t->fd ); - - D("from_remote: transport %p SYNC online (%d)\n", t, t->sync_token + 1); - p = get_apacket(); - p->msg.command = A_SYNC; - p->msg.arg0 = 1; - p->msg.arg1 = ++(t->sync_token); - p->msg.magic = A_SYNC ^ 0xffffffff; - if(write_packet(t->fd, &p)) { - put_apacket(p); - D("from_remote: failed to write SYNC apacket to transport %p", t); - goto oops; - } - - D("from_remote: data pump for transport %p\n", t); - for(;;) { - p = get_apacket(); - - if(t->read_from_remote(p, t) == 0){ - D("from_remote: received remote packet, sending to transport %p\n", - t); - if(write_packet(t->fd, &p)){ - put_apacket(p); - D("from_remote: failed to write apacket to transport %p", t); - goto oops; - } - } else { - D("from_remote: remote read failed for transport %p\n", p); - put_apacket(p); - break; - } - } - - D("from_remote: SYNC offline for transport %p\n", t); - p = get_apacket(); - p->msg.command = A_SYNC; - p->msg.arg0 = 0; - p->msg.arg1 = 0; - p->msg.magic = A_SYNC ^ 0xffffffff; - if(write_packet(t->fd, &p)) { - put_apacket(p); - D("from_remote: failed to write SYNC apacket to transport %p", t); - } - -oops: - D("from_remote: thread is exiting for transport %p\n", t); - kick_transport(t); - transport_unref(t); - return 0; -} - -static void *input_thread(void *_t) -{ - atransport *t = _t; - apacket *p; - int active = 0; - - D("to_remote: starting input_thread for %p, reading from fd %d\n", - t, t->fd); - - for(;;){ - if(read_packet(t->fd, &p)) { - D("to_remote: failed to read apacket from transport %p on fd %d\n", - t, t->fd ); - break; - } - if(p->msg.command == A_SYNC){ - if(p->msg.arg0 == 0) { - D("to_remote: transport %p SYNC offline\n", t); - put_apacket(p); - break; - } else { - if(p->msg.arg1 == t->sync_token) { - D("to_remote: transport %p SYNC online\n", t); - active = 1; - } else { - D("to_remote: trandport %p ignoring SYNC %d != %d\n", - t, p->msg.arg1, t->sync_token); - } - } - } else { - if(active) { - D("to_remote: transport %p got packet, sending to remote\n", t); - t->write_to_remote(p, t); - } else { - D("to_remote: transport %p ignoring packet while offline\n", t); - } - } - - put_apacket(p); - } - - // this is necessary to avoid a race condition that occured when a transport closes - // while a client socket is still active. - close_all_sockets(t); - - D("to_remote: thread is exiting for transport %p, fd %d\n", t, t->fd); - kick_transport(t); - transport_unref(t); - return 0; -} - - -static int transport_registration_send = -1; -static int transport_registration_recv = -1; -static fdevent transport_registration_fde; - - -#if ADB_HOST -static int list_transports_msg(char* buffer, size_t bufferlen) -{ - char head[5]; - int len; - - len = list_transports(buffer+4, bufferlen-4); - snprintf(head, sizeof(head), "%04x", len); - memcpy(buffer, head, 4); - len += 4; - return len; -} - -/* this adds support required by the 'track-devices' service. - * this is used to send the content of "list_transport" to any - * number of client connections that want it through a single - * live TCP connection - */ -typedef struct device_tracker device_tracker; -struct device_tracker { - asocket socket; - int update_needed; - device_tracker* next; -}; - -/* linked list of all device trackers */ -static device_tracker* device_tracker_list; - -static void -device_tracker_remove( device_tracker* tracker ) -{ - device_tracker** pnode = &device_tracker_list; - device_tracker* node = *pnode; - - adb_mutex_lock( &transport_lock ); - while (node) { - if (node == tracker) { - *pnode = node->next; - break; - } - pnode = &node->next; - node = *pnode; - } - adb_mutex_unlock( &transport_lock ); -} - -static void -device_tracker_close( asocket* socket ) -{ - device_tracker* tracker = (device_tracker*) socket; - asocket* peer = socket->peer; - - D( "device tracker %p removed\n", tracker); - if (peer) { - peer->peer = NULL; - peer->close(peer); - } - device_tracker_remove(tracker); - free(tracker); -} - -static int -device_tracker_enqueue( asocket* socket, apacket* p ) -{ - /* you can't read from a device tracker, close immediately */ - put_apacket(p); - device_tracker_close(socket); - return -1; -} - -static int -device_tracker_send( device_tracker* tracker, - const char* buffer, - int len ) -{ - apacket* p = get_apacket(); - asocket* peer = tracker->socket.peer; - - memcpy(p->data, buffer, len); - p->len = len; - return peer->enqueue( peer, p ); -} - - -static void -device_tracker_ready( asocket* socket ) -{ - device_tracker* tracker = (device_tracker*) socket; - - /* we want to send the device list when the tracker connects - * for the first time, even if no update occured */ - if (tracker->update_needed > 0) { - char buffer[1024]; - int len; - - tracker->update_needed = 0; - - len = list_transports_msg(buffer, sizeof(buffer)); - device_tracker_send(tracker, buffer, len); - } -} - - -asocket* -create_device_tracker(void) -{ - device_tracker* tracker = calloc(1,sizeof(*tracker)); - - if(tracker == 0) fatal("cannot allocate device tracker"); - - D( "device tracker %p created\n", tracker); - - tracker->socket.enqueue = device_tracker_enqueue; - tracker->socket.ready = device_tracker_ready; - tracker->socket.close = device_tracker_close; - tracker->update_needed = 1; - - tracker->next = device_tracker_list; - device_tracker_list = tracker; - - return &tracker->socket; -} - - -/* call this function each time the transport list has changed */ -void update_transports(void) -{ - char buffer[1024]; - int len; - device_tracker* tracker; - - len = list_transports_msg(buffer, sizeof(buffer)); - - tracker = device_tracker_list; - while (tracker != NULL) { - device_tracker* next = tracker->next; - /* note: this may destroy the tracker if the connection is closed */ - device_tracker_send(tracker, buffer, len); - tracker = next; - } -} -#else -void update_transports(void) -{ - // nothing to do on the device side -} -#endif // ADB_HOST - -typedef struct tmsg tmsg; -struct tmsg -{ - atransport *transport; - int action; -}; - -static int -transport_read_action(int fd, struct tmsg* m) -{ - char *p = (char*)m; - int len = sizeof(*m); - int r; - - while(len > 0) { - r = adb_read(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - if((r < 0) && (errno == EINTR)) continue; - D("transport_read_action: on fd %d, error %d: %s\n", - fd, errno, strerror(errno)); - return -1; - } - } - return 0; -} - -static int -transport_write_action(int fd, struct tmsg* m) -{ - char *p = (char*)m; - int len = sizeof(*m); - int r; - - while(len > 0) { - r = adb_write(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - if((r < 0) && (errno == EINTR)) continue; - D("transport_write_action: on fd %d, error %d: %s\n", - fd, errno, strerror(errno)); - return -1; - } - } - return 0; -} - -static void transport_registration_func(int _fd, unsigned ev, void *data) -{ - tmsg m; - adb_thread_t output_thread_ptr; - adb_thread_t input_thread_ptr; - int s[2]; - atransport *t; - - if(!(ev & FDE_READ)) { - return; - } - - if(transport_read_action(_fd, &m)) { - fatal_errno("cannot read transport registration socket"); - } - - t = m.transport; - - if(m.action == 0){ - D("transport: %p removing and free'ing %d\n", t, t->transport_socket); - - /* IMPORTANT: the remove closes one half of the - ** socket pair. The close closes the other half. - */ - fdevent_remove(&(t->transport_fde)); - adb_close(t->fd); - - adb_mutex_lock(&transport_lock); - t->next->prev = t->prev; - t->prev->next = t->next; - adb_mutex_unlock(&transport_lock); - - run_transport_disconnects(t); - - if (t->product) - free(t->product); - if (t->serial) - free(t->serial); - - memset(t,0xee,sizeof(atransport)); - free(t); - - update_transports(); - return; - } - - /* initial references are the two threads */ - t->ref_count = 2; - - if(adb_socketpair(s)) { - fatal_errno("cannot open transport socketpair"); - } - - D("transport: %p (%d,%d) starting\n", t, s[0], s[1]); - - t->transport_socket = s[0]; - t->fd = s[1]; - - /* put us on the master device list */ - adb_mutex_lock(&transport_lock); - t->next = &transport_list; - t->prev = transport_list.prev; - t->next->prev = t; - t->prev->next = t; - adb_mutex_unlock(&transport_lock); - - D("transport: %p install %d\n", t, t->transport_socket ); - fdevent_install(&(t->transport_fde), - t->transport_socket, - transport_socket_events, - t); - - fdevent_set(&(t->transport_fde), FDE_READ); - - if(adb_thread_create(&input_thread_ptr, input_thread, t)){ - fatal_errno("cannot create input thread"); - } - - if(adb_thread_create(&output_thread_ptr, output_thread, t)){ - fatal_errno("cannot create output thread"); - } - - t->disconnects.next = t->disconnects.prev = &t->disconnects; - - update_transports(); -} - -void init_transport_registration(void) -{ - int s[2]; - - if(adb_socketpair(s)){ - fatal_errno("cannot open transport registration socketpair"); - } - - transport_registration_send = s[0]; - transport_registration_recv = s[1]; - - fdevent_install(&transport_registration_fde, - transport_registration_recv, - transport_registration_func, - 0); - - fdevent_set(&transport_registration_fde, FDE_READ); -} - -/* the fdevent select pump is single threaded */ -static void register_transport(atransport *transport) -{ - tmsg m; - m.transport = transport; - m.action = 1; - D("transport: %p registered\n", transport); - if(transport_write_action(transport_registration_send, &m)) { - fatal_errno("cannot write transport registration socket\n"); - } -} - -static void remove_transport(atransport *transport) -{ - tmsg m; - m.transport = transport; - m.action = 0; - D("transport: %p removed\n", transport); - if(transport_write_action(transport_registration_send, &m)) { - fatal_errno("cannot write transport registration socket\n"); - } -} - - -static void transport_unref(atransport *t) -{ - if (t) { - adb_mutex_lock(&transport_lock); - t->ref_count--; - D("transport: %p R- (ref=%d)\n", t, t->ref_count); - if (t->ref_count == 0) { - D("transport: %p kicking and closing\n", t); - if (!t->kicked) { - t->kicked = 1; - t->kick(t); - } - t->close(t); - remove_transport(t); - } - adb_mutex_unlock(&transport_lock); - } -} - -void add_transport_disconnect(atransport* t, adisconnect* dis) -{ - adb_mutex_lock(&transport_lock); - dis->next = &t->disconnects; - dis->prev = dis->next->prev; - dis->prev->next = dis; - dis->next->prev = dis; - adb_mutex_unlock(&transport_lock); -} - -void remove_transport_disconnect(atransport* t, adisconnect* dis) -{ - dis->prev->next = dis->next; - dis->next->prev = dis->prev; - dis->next = dis->prev = dis; -} - - -atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out) -{ - atransport *t; - atransport *result = NULL; - int ambiguous = 0; - -retry: - if (error_out) - *error_out = "device not found"; - - adb_mutex_lock(&transport_lock); - for (t = transport_list.next; t != &transport_list; t = t->next) { - /* check for matching serial number */ - if (serial) { - if (t->serial && !strcmp(serial, t->serial)) { - result = t; - break; - } - } else { - if (ttype == kTransportUsb && t->type == kTransportUsb) { - if (result) { - if (error_out) - *error_out = "more than one device"; - ambiguous = 1; - result = NULL; - break; - } - result = t; - } else if (ttype == kTransportLocal && t->type == kTransportLocal) { - if (result) { - if (error_out) - *error_out = "more than one emulator"; - ambiguous = 1; - result = NULL; - break; - } - result = t; - } else if (ttype == kTransportAny) { - if (result) { - if (error_out) - *error_out = "more than one device and emulator"; - ambiguous = 1; - result = NULL; - break; - } - result = t; - } - } - } - adb_mutex_unlock(&transport_lock); - - if (result) { - /* offline devices are ignored -- they are either being born or dying */ - if (result && result->connection_state == CS_OFFLINE) { - if (error_out) - *error_out = "device offline"; - result = NULL; - } - - /* check for required connection state */ - if (result && state != CS_ANY && result->connection_state != state) { - if (error_out) - *error_out = "invalid device state"; - result = NULL; - } - } - - if (result) { - /* found one that we can take */ - if (error_out) - *error_out = NULL; - } else if (state != CS_ANY && (serial || !ambiguous)) { - adb_sleep_ms(1000); - goto retry; - } - - return result; -} - -#if ADB_HOST -static const char *statename(atransport *t) -{ - switch(t->connection_state){ - case CS_OFFLINE: return "offline"; - case CS_BOOTLOADER: return "bootloader"; - case CS_DEVICE: return "device"; - case CS_HOST: return "host"; - case CS_RECOVERY: return "recovery"; - default: return "unknown"; - } -} - -int list_transports(char *buf, size_t bufsize) -{ - char* p = buf; - char* end = buf + bufsize; - int len; - atransport *t; - - /* XXX OVERRUN PROBLEMS XXX */ - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - len = snprintf(p, end - p, "%s\t%s\n", - t->serial ? t->serial : "", - statename(t)); - - if (p + len >= end) { - /* discard last line if buffer is too short */ - break; - } - p += len; - } - p[0] = 0; - adb_mutex_unlock(&transport_lock); - return p - buf; -} - - -/* hack for osx */ -void close_usb_devices() -{ - atransport *t; - - adb_mutex_lock(&transport_lock); - for(t = transport_list.next; t != &transport_list; t = t->next) { - if ( !t->kicked ) { - t->kicked = 1; - t->kick(t); - } - } - adb_mutex_unlock(&transport_lock); -} -#endif // ADB_HOST - -void register_socket_transport(int s, const char *serial, int port) -{ - atransport *t = calloc(1, sizeof(atransport)); - D("transport: %p init'ing for socket %d, on port %d\n", t, s, port); - if ( init_socket_transport(t, s, port) < 0 ) { - adb_close(s); - free(t); - return; - } - if(serial) { - t->serial = strdup(serial); - } - register_transport(t); -} - -void register_usb_transport(usb_handle *usb, const char *serial) -{ - atransport *t = calloc(1, sizeof(atransport)); - D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb, - serial ? serial : ""); - init_usb_transport(t, usb); - if(serial) { - t->serial = strdup(serial); - } - register_transport(t); -} - - -#undef TRACE_TAG -#define TRACE_TAG TRACE_RWX - -int readx(int fd, void *ptr, size_t len) -{ - char *p = ptr; - int r; -#if ADB_TRACE - int len0 = len; -#endif - D("readx: %d %p %d\n", fd, ptr, (int)len); - while(len > 0) { - r = adb_read(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - D("readx: %d %d %s\n", fd, r, strerror(errno)); - if((r < 0) && (errno == EINTR)) continue; - return -1; - } - } - -#if ADB_TRACE - D("readx: %d ok: ", fd); - dump_hex( ptr, len0 ); -#endif - return 0; -} - -int writex(int fd, const void *ptr, size_t len) -{ - char *p = (char*) ptr; - int r; - -#if ADB_TRACE - D("writex: %d %p %d: ", fd, ptr, (int)len); - dump_hex( ptr, len ); -#endif - while(len > 0) { - r = adb_write(fd, p, len); - if(r > 0) { - len -= r; - p += r; - } else { - D("writex: %d %d %s\n", fd, r, strerror(errno)); - if((r < 0) && (errno == EINTR)) continue; - return -1; - } - } - - D("writex: %d ok\n", fd); - return 0; -} - -int check_header(apacket *p) -{ - if(p->msg.magic != (p->msg.command ^ 0xffffffff)) { - D("check_header(): invalid magic\n"); - return -1; - } - - if(p->msg.data_length > MAX_PAYLOAD) { - D("check_header(): %d > MAX_PAYLOAD\n", p->msg.data_length); - return -1; - } - - return 0; -} - -int check_data(apacket *p) -{ - unsigned count, sum; - unsigned char *x; - - count = p->msg.data_length; - x = p->data; - sum = 0; - while(count-- > 0) { - sum += *x++; - } - - if(sum != p->msg.data_check) { - return -1; - } else { - return 0; - } -} - diff --git a/adb/transport_local.c b/adb/transport_local.c deleted file mode 100644 index be01f290ceae2303ad835d74f34f1daf1460573e..0000000000000000000000000000000000000000 --- a/adb/transport_local.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "sysdeps.h" -#include <sys/types.h> - -#define TRACE_TAG TRACE_TRANSPORT -#include "adb.h" - -#ifdef __ppc__ -#define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) -static inline void fix_endians(apacket *p) -{ - p->msg.command = H4(p->msg.command); - p->msg.arg0 = H4(p->msg.arg0); - p->msg.arg1 = H4(p->msg.arg1); - p->msg.data_length = H4(p->msg.data_length); - p->msg.data_check = H4(p->msg.data_check); - p->msg.magic = H4(p->msg.magic); -} -#else -#define fix_endians(p) do {} while (0) -#endif - -#if ADB_HOST -/* we keep a list of opened transports, transport 0 is bound to 5555, - * transport 1 to 5557, .. transport n to 5555 + n*2. the list is used - * to detect when we're trying to connect twice to a given local transport - */ -#define ADB_LOCAL_TRANSPORT_MAX 16 - -ADB_MUTEX_DEFINE( local_transports_lock ); - -static atransport* local_transports[ ADB_LOCAL_TRANSPORT_MAX ]; -#endif /* ADB_HOST */ - -static int remote_read(apacket *p, atransport *t) -{ - if(readx(t->sfd, &p->msg, sizeof(amessage))){ - D("remote local: read terminated (message)\n"); - return -1; - } - - fix_endians(p); - -#if 0 && defined __ppc__ - D("read remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", - p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); -#endif - if(check_header(p)) { - D("bad header: terminated (data)\n"); - return -1; - } - - if(readx(t->sfd, p->data, p->msg.data_length)){ - D("remote local: terminated (data)\n"); - return -1; - } - - if(check_data(p)) { - D("bad data: terminated (data)\n"); - return -1; - } - - return 0; -} - -static int remote_write(apacket *p, atransport *t) -{ - int length = p->msg.data_length; - - fix_endians(p); - -#if 0 && defined __ppc__ - D("write remote packet: %04x arg0=%0x arg1=%0x data_length=%0x data_check=%0x magic=%0x\n", - p->msg.command, p->msg.arg0, p->msg.arg1, p->msg.data_length, p->msg.data_check, p->msg.magic); -#endif - if(writex(t->sfd, &p->msg, sizeof(amessage) + length)) { - D("remote local: write terminated\n"); - return -1; - } - - return 0; -} - - -int local_connect(int port) -{ - char buf[64]; - int fd = -1; - -#if ADB_HOST - const char *host = getenv("ADBHOST"); - if (host) { - fd = socket_network_client(host, port, SOCK_STREAM); - } -#endif - if (fd < 0) { - fd = socket_loopback_client(port, SOCK_STREAM); - } - - if (fd >= 0) { - D("client: connected on remote on fd %d\n", fd); - close_on_exec(fd); - disable_tcp_nagle(fd); - snprintf(buf, sizeof buf, "%s%d", LOCAL_CLIENT_PREFIX, port - 1); - register_socket_transport(fd, buf, port); - return 0; - } - return -1; -} - - -static void *client_socket_thread(void *x) -{ -#if ADB_HOST - int port = ADB_LOCAL_TRANSPORT_PORT; - int count = ADB_LOCAL_TRANSPORT_MAX; - - D("transport: client_socket_thread() starting\n"); - - /* try to connect to any number of running emulator instances */ - /* this is only done when ADB starts up. later, each new emulator */ - /* will send a message to ADB to indicate that is is starting up */ - for ( ; count > 0; count--, port += 2 ) { - (void) local_connect(port); - } -#endif - return 0; -} - -static void *server_socket_thread(void *x) -{ - int serverfd, fd; - struct sockaddr addr; - socklen_t alen; - - D("transport: server_socket_thread() starting\n"); - serverfd = -1; - for(;;) { - if(serverfd == -1) { - serverfd = socket_inaddr_any_server(ADB_LOCAL_TRANSPORT_PORT, SOCK_STREAM); - if(serverfd < 0) { - D("server: cannot bind socket yet\n"); - adb_sleep_ms(1000); - continue; - } - close_on_exec(serverfd); - } - - alen = sizeof(addr); - D("server: trying to get new connection from %d\n", ADB_LOCAL_TRANSPORT_PORT); - fd = adb_socket_accept(serverfd, &addr, &alen); - if(fd >= 0) { - D("server: new connection on fd %d\n", fd); - close_on_exec(fd); - disable_tcp_nagle(fd); - register_socket_transport(fd,"host",ADB_LOCAL_TRANSPORT_PORT); - } - } - D("transport: server_socket_thread() exiting\n"); - return 0; -} - -void local_init(void) -{ - adb_thread_t thr; - void* (*func)(void *); - - if(HOST) { - func = client_socket_thread; - } else { - func = server_socket_thread; - } - - D("transport: local %s init\n", HOST ? "client" : "server"); - - if(adb_thread_create(&thr, func, 0)) { - fatal_errno("cannot create local socket %s thread", - HOST ? "client" : "server"); - } -} - -static void remote_kick(atransport *t) -{ - int fd = t->sfd; - t->sfd = -1; - adb_close(fd); - -#if ADB_HOST - if(HOST) { - int nn; - adb_mutex_lock( &local_transports_lock ); - for (nn = 0; nn < ADB_LOCAL_TRANSPORT_MAX; nn++) { - if (local_transports[nn] == t) { - local_transports[nn] = NULL; - break; - } - } - adb_mutex_unlock( &local_transports_lock ); - } -#endif -} - -static void remote_close(atransport *t) -{ - adb_close(t->fd); -} - -int init_socket_transport(atransport *t, int s, int port) -{ - int fail = 0; - - t->kick = remote_kick; - t->close = remote_close; - t->read_from_remote = remote_read; - t->write_to_remote = remote_write; - t->sfd = s; - t->sync_token = 1; - t->connection_state = CS_OFFLINE; - t->type = kTransportLocal; - -#if ADB_HOST - if (HOST) { - adb_mutex_lock( &local_transports_lock ); - { - int index = (port - ADB_LOCAL_TRANSPORT_PORT)/2; - - if (!(port & 1) || index < 0 || index >= ADB_LOCAL_TRANSPORT_MAX) { - D("bad local transport port number: %d\n", port); - fail = -1; - } - else if (local_transports[index] != NULL) { - D("local transport for port %d already registered (%p)?\n", - port, local_transports[index]); - fail = -1; - } - else - local_transports[index] = t; - } - adb_mutex_unlock( &local_transports_lock ); - } -#endif - return fail; -} diff --git a/adb/transport_usb.c b/adb/transport_usb.c deleted file mode 100644 index 01c4a7edeb9f79278a0f0d8a6c7bd4b434595e63..0000000000000000000000000000000000000000 --- a/adb/transport_usb.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <sysdeps.h> - -#define TRACE_TAG TRACE_TRANSPORT -#include "adb.h" - -/* XXX better define? */ -#ifdef __ppc__ -#define H4(x) (((x) & 0xFF000000) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | (((x) & 0x000000FF) << 24) -static inline void fix_endians(apacket *p) -{ - p->msg.command = H4(p->msg.command); - p->msg.arg0 = H4(p->msg.arg0); - p->msg.arg1 = H4(p->msg.arg1); - p->msg.data_length = H4(p->msg.data_length); - p->msg.data_check = H4(p->msg.data_check); - p->msg.magic = H4(p->msg.magic); -} -unsigned host_to_le32(unsigned n) -{ - return H4(n); -} -#else -#define fix_endians(p) do {} while (0) -unsigned host_to_le32(unsigned n) -{ - return n; -} -#endif - -static int remote_read(apacket *p, atransport *t) -{ - if(usb_read(t->usb, &p->msg, sizeof(amessage))){ - D("remote usb: read terminated (message)\n"); - return -1; - } - - fix_endians(p); - - if(check_header(p)) { - D("remote usb: check_header failed\n"); - return -1; - } - - if(p->msg.data_length) { - if(usb_read(t->usb, p->data, p->msg.data_length)){ - D("remote usb: terminated (data)\n"); - return -1; - } - } - - if(check_data(p)) { - D("remote usb: check_data failed\n"); - return -1; - } - - return 0; -} - -static int remote_write(apacket *p, atransport *t) -{ - unsigned size = p->msg.data_length; - - fix_endians(p); - - if(usb_write(t->usb, &p->msg, sizeof(amessage))) { - D("remote usb: 1 - write terminated\n"); - return -1; - } - if(p->msg.data_length == 0) return 0; - if(usb_write(t->usb, &p->data, size)) { - D("remote usb: 2 - write terminated\n"); - return -1; - } - - return 0; -} - -static void remote_close(atransport *t) -{ - usb_close(t->usb); - t->usb = 0; -} - -static void remote_kick(atransport *t) -{ - usb_kick(t->usb); -} - -void init_usb_transport(atransport *t, usb_handle *h) -{ - D("transport: usb\n"); - t->close = remote_close; - t->kick = remote_kick; - t->read_from_remote = remote_read; - t->write_to_remote = remote_write; - t->sync_token = 1; - t->connection_state = CS_OFFLINE; - t->type = kTransportUsb; - t->usb = h; - -#if ADB_HOST - HOST = 1; -#else - HOST = 0; -#endif -} - -int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol) -{ - if (vid == VENDOR_ID_GOOGLE) { - /* might support adb */ - } else if (vid == VENDOR_ID_HTC) { - /* might support adb */ - } else { - /* not supported */ - return 0; - } - - /* class:vendor (0xff) subclass:android (0x42) proto:adb (0x01) */ - if(usb_class == 0xff) { - if((usb_subclass == 0x42) && (usb_protocol == 0x01)) { - return 1; - } - } - - return 0; -} diff --git a/adb/usb_linux.c b/adb/usb_linux.c deleted file mode 100644 index 32ce0a9e7ed69739d73bf076eb1745794912df00..0000000000000000000000000000000000000000 --- a/adb/usb_linux.c +++ /dev/null @@ -1,654 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <dirent.h> -#include <fcntl.h> -#include <errno.h> -#include <ctype.h> - -#include <linux/usbdevice_fs.h> -#include <linux/version.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) -#include <linux/usb/ch9.h> -#else -#include <linux/usb_ch9.h> -#endif -#include <asm/byteorder.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_USB -#include "adb.h" - - -/* usb scan debugging is waaaay too verbose */ -#define DBGX(x...) - -static adb_mutex_t usb_lock = ADB_MUTEX_INITIALIZER; - -struct usb_handle -{ - usb_handle *prev; - usb_handle *next; - - char fname[64]; - int desc; - unsigned char ep_in; - unsigned char ep_out; - - unsigned zero_mask; - - struct usbdevfs_urb urb_in; - struct usbdevfs_urb urb_out; - - int urb_in_busy; - int urb_out_busy; - int dead; - - adb_cond_t notify; - adb_mutex_t lock; - - // for garbage collecting disconnected devices - int mark; - - // ID of thread currently in REAPURB - pthread_t reaper_thread; -}; - -static usb_handle handle_list = { - .prev = &handle_list, - .next = &handle_list, -}; - -static int known_device(const char *dev_name) -{ - usb_handle *usb; - - adb_mutex_lock(&usb_lock); - for(usb = handle_list.next; usb != &handle_list; usb = usb->next){ - if(!strcmp(usb->fname, dev_name)) { - // set mark flag to indicate this device is still alive - usb->mark = 1; - adb_mutex_unlock(&usb_lock); - return 1; - } - } - adb_mutex_unlock(&usb_lock); - return 0; -} - -static void kick_disconnected_devices() -{ - usb_handle *usb; - - adb_mutex_lock(&usb_lock); - // kick any devices in the device list that were not found in the device scan - for(usb = handle_list.next; usb != &handle_list; usb = usb->next){ - if (usb->mark == 0) { - usb_kick(usb); - } else { - usb->mark = 0; - } - } - adb_mutex_unlock(&usb_lock); - -} - -static void register_device(const char *dev_name, unsigned char ep_in, unsigned char ep_out, - int ifc, const char *serial, unsigned zero_mask); - -static inline int badname(const char *name) -{ - while(*name) { - if(!isdigit(*name++)) return 1; - } - return 0; -} - -static int find_usb_device(const char *base, - void (*register_device_callback) (const char *, unsigned char, unsigned char, int, const char *, unsigned)) -{ - char busname[32], devname[32]; - unsigned char local_ep_in, local_ep_out; - DIR *busdir , *devdir ; - struct dirent *de; - int fd ; - int found_device = 0; - char serial[256]; - - busdir = opendir(base); - if(busdir == 0) return 0; - - while((de = readdir(busdir)) != 0) { - if(badname(de->d_name)) continue; - - snprintf(busname, sizeof busname, "%s/%s", base, de->d_name); - devdir = opendir(busname); - if(devdir == 0) continue; - -// DBGX("[ scanning %s ]\n", busname); - while((de = readdir(devdir))) { - unsigned char devdesc[256]; - unsigned char* bufptr = devdesc; - struct usb_device_descriptor* device; - struct usb_config_descriptor* config; - struct usb_interface_descriptor* interface; - struct usb_endpoint_descriptor *ep1, *ep2; - unsigned zero_mask = 0; - unsigned vid, pid; - int i, interfaces; - size_t desclength; - - if(badname(de->d_name)) continue; - snprintf(devname, sizeof devname, "%s/%s", busname, de->d_name); - - if(known_device(devname)) { - DBGX("skipping %s\n", devname); - continue; - } - -// DBGX("[ scanning %s ]\n", devname); - if((fd = unix_open(devname, O_RDWR)) < 0) { - continue; - } - - desclength = adb_read(fd, devdesc, sizeof(devdesc)); - - // should have device and configuration descriptors, and atleast two endpoints - if (desclength < USB_DT_DEVICE_SIZE + USB_DT_CONFIG_SIZE) { - D("desclength %d is too small\n", desclength); - adb_close(fd); - continue; - } - - device = (struct usb_device_descriptor*)bufptr; - bufptr += USB_DT_DEVICE_SIZE; - - if((device->bLength != USB_DT_DEVICE_SIZE) || (device->bDescriptorType != USB_DT_DEVICE)) { - adb_close(fd); - continue; - } - - vid = __le16_to_cpu(device->idVendor); - pid = __le16_to_cpu(device->idProduct); - pid = devdesc[10] | (devdesc[11] << 8); - DBGX("[ %s is V:%04x P:%04x ]\n", devname, vid, pid); - - // should have config descriptor next - config = (struct usb_config_descriptor *)bufptr; - bufptr += USB_DT_CONFIG_SIZE; - if (config->bLength != USB_DT_CONFIG_SIZE || config->bDescriptorType != USB_DT_CONFIG) { - D("usb_config_descriptor not found\n"); - adb_close(fd); - continue; - } - - // loop through all the interfaces and look for the ADB interface - interfaces = config->bNumInterfaces; - for (i = 0; i < interfaces; i++) { - if (bufptr + USB_DT_ENDPOINT_SIZE > devdesc + desclength) - break; - - interface = (struct usb_interface_descriptor *)bufptr; - bufptr += USB_DT_INTERFACE_SIZE; - if (interface->bLength != USB_DT_INTERFACE_SIZE || - interface->bDescriptorType != USB_DT_INTERFACE) { - D("usb_interface_descriptor not found\n"); - break; - } - - DBGX("bInterfaceClass: %d, bInterfaceSubClass: %d," - "bInterfaceProtocol: %d, bNumEndpoints: %d\n", - interface->bInterfaceClass, interface->bInterfaceSubClass, - interface->bInterfaceProtocol, interface->bNumEndpoints); - - if (interface->bNumEndpoints == 2 && - is_adb_interface(vid, pid, interface->bInterfaceClass, - interface->bInterfaceSubClass, interface->bInterfaceProtocol)) { - - DBGX("looking for bulk endpoints\n"); - // looks like ADB... - ep1 = (struct usb_endpoint_descriptor *)bufptr; - bufptr += USB_DT_ENDPOINT_SIZE; - ep2 = (struct usb_endpoint_descriptor *)bufptr; - bufptr += USB_DT_ENDPOINT_SIZE; - - if (bufptr > devdesc + desclength || - ep1->bLength != USB_DT_ENDPOINT_SIZE || - ep1->bDescriptorType != USB_DT_ENDPOINT || - ep2->bLength != USB_DT_ENDPOINT_SIZE || - ep2->bDescriptorType != USB_DT_ENDPOINT) { - D("endpoints not found\n"); - break; - } - - // both endpoints should be bulk - if (ep1->bmAttributes != USB_ENDPOINT_XFER_BULK || - ep2->bmAttributes != USB_ENDPOINT_XFER_BULK) { - D("bulk endpoints not found\n"); - continue; - } - - /* aproto 01 needs 0 termination */ - if(interface->bInterfaceProtocol == 0x01) { - zero_mask = ep1->wMaxPacketSize - 1; - } - - // we have a match. now we just need to figure out which is in and which is out. - if (ep1->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { - local_ep_in = ep1->bEndpointAddress; - local_ep_out = ep2->bEndpointAddress; - } else { - local_ep_in = ep2->bEndpointAddress; - local_ep_out = ep1->bEndpointAddress; - } - - // read the device's serial number - serial[0] = 0; - memset(serial, 0, sizeof(serial)); - if (device->iSerialNumber) { - struct usbdevfs_ctrltransfer ctrl; - __u16 buffer[128]; - int result; - - memset(buffer, 0, sizeof(buffer)); - memset(&ctrl, 0, sizeof(ctrl)); - - ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE; - ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; - ctrl.wValue = (USB_DT_STRING << 8) | device->iSerialNumber; - ctrl.wIndex = 0; - ctrl.wLength = sizeof(buffer); - ctrl.data = buffer; - - result = ioctl(fd, USBDEVFS_CONTROL, &ctrl); - if (result > 0) { - int i; - // skip first word, and copy the rest to the serial string, changing shorts to bytes. - result /= 2; - for (i = 1; i < result; i++) - serial[i - 1] = buffer[i]; - serial[i - 1] = 0; - } - } - - register_device_callback(devname, local_ep_in, local_ep_out, - interface->bInterfaceNumber, serial, zero_mask); - - found_device = 1; - break; - } else { - // skip to next interface - bufptr += (interface->bNumEndpoints * USB_DT_ENDPOINT_SIZE); - } - } // end of for - - adb_close(fd); - } // end of devdir while - closedir(devdir); - } //end of busdir while - closedir(busdir); - - return found_device; -} - -void usb_cleanup() -{ -} - -static int usb_bulk_write(usb_handle *h, const void *data, int len) -{ - struct usbdevfs_urb *urb = &h->urb_out; - int res; - - memset(urb, 0, sizeof(*urb)); - urb->type = USBDEVFS_URB_TYPE_BULK; - urb->endpoint = h->ep_out; - urb->status = -1; - urb->buffer = (void*) data; - urb->buffer_length = len; - - D("++ write ++\n"); - - adb_mutex_lock(&h->lock); - if(h->dead) { - res = -1; - goto fail; - } - do { - res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb); - } while((res < 0) && (errno == EINTR)); - - if(res < 0) { - goto fail; - } - - res = -1; - h->urb_out_busy = 1; - for(;;) { - adb_cond_wait(&h->notify, &h->lock); - if(h->dead) { - break; - } - if(h->urb_out_busy == 0) { - if(urb->status == 0) { - res = urb->actual_length; - } - break; - } - } -fail: - adb_mutex_unlock(&h->lock); - D("-- write --\n"); - return res; -} - -static int usb_bulk_read(usb_handle *h, void *data, int len) -{ - struct usbdevfs_urb *urb = &h->urb_in; - struct usbdevfs_urb *out = NULL; - int res; - - memset(urb, 0, sizeof(*urb)); - urb->type = USBDEVFS_URB_TYPE_BULK; - urb->endpoint = h->ep_in; - urb->status = -1; - urb->buffer = data; - urb->buffer_length = len; - - - adb_mutex_lock(&h->lock); - if(h->dead) { - res = -1; - goto fail; - } - do { - res = ioctl(h->desc, USBDEVFS_SUBMITURB, urb); - } while((res < 0) && (errno == EINTR)); - - if(res < 0) { - goto fail; - } - - h->urb_in_busy = 1; - for(;;) { - D("[ reap urb - wait ]\n"); - h->reaper_thread = pthread_self(); - adb_mutex_unlock(&h->lock); - res = ioctl(h->desc, USBDEVFS_REAPURB, &out); - adb_mutex_lock(&h->lock); - h->reaper_thread = 0; - if(h->dead) { - res = -1; - break; - } - if(res < 0) { - if(errno == EINTR) { - continue; - } - D("[ reap urb - error ]\n"); - break; - } - D("[ urb @%p status = %d, actual = %d ]\n", - out, out->status, out->actual_length); - - if(out == &h->urb_in) { - D("[ reap urb - IN complete ]\n"); - h->urb_in_busy = 0; - if(urb->status == 0) { - res = urb->actual_length; - } else { - res = -1; - } - break; - } - if(out == &h->urb_out) { - D("[ reap urb - OUT compelete ]\n"); - h->urb_out_busy = 0; - adb_cond_broadcast(&h->notify); - } - } -fail: - adb_mutex_unlock(&h->lock); - return res; -} - - -int usb_write(usb_handle *h, const void *_data, int len) -{ - unsigned char *data = (unsigned char*) _data; - int n; - int need_zero = 0; - - if(h->zero_mask) { - /* if we need 0-markers and our transfer - ** is an even multiple of the packet size, - ** we make note of it - */ - if(!(len & h->zero_mask)) { - need_zero = 1; - } - } - - while(len > 0) { - int xfer = (len > 4096) ? 4096 : len; - - n = usb_bulk_write(h, data, xfer); - if(n != xfer) { - D("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - - len -= xfer; - data += xfer; - } - - if(need_zero){ - n = usb_bulk_write(h, _data, 0); - return n; - } - - return 0; -} - -int usb_read(usb_handle *h, void *_data, int len) -{ - unsigned char *data = (unsigned char*) _data; - int n; - - D("++ usb_read ++\n"); - while(len > 0) { - int xfer = (len > 4096) ? 4096 : len; - - D("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname); - n = usb_bulk_read(h, data, xfer); - D("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname); - if(n != xfer) { - if((errno == ETIMEDOUT) && (h->desc != -1)) { - D("[ timeout ]\n"); - if(n > 0){ - data += n; - len -= n; - } - continue; - } - D("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - - len -= xfer; - data += xfer; - } - - D("-- usb_read --\n"); - return 0; -} - -void usb_kick(usb_handle *h) -{ - D("[ kicking %p (fd = %d) ]\n", h, h->desc); - adb_mutex_lock(&h->lock); - if(h->dead == 0) { - h->dead = 1; - - /* HACK ALERT! - ** Sometimes we get stuck in ioctl(USBDEVFS_REAPURB). - ** This is a workaround for that problem. - */ - if (h->reaper_thread) { - pthread_kill(h->reaper_thread, SIGALRM); - } - - /* cancel any pending transactions - ** these will quietly fail if the txns are not active, - ** but this ensures that a reader blocked on REAPURB - ** will get unblocked - */ - ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_in); - ioctl(h->desc, USBDEVFS_DISCARDURB, &h->urb_out); - h->urb_in.status = -ENODEV; - h->urb_out.status = -ENODEV; - h->urb_in_busy = 0; - h->urb_out_busy = 0; - adb_cond_broadcast(&h->notify); - } - adb_mutex_unlock(&h->lock); -} - -int usb_close(usb_handle *h) -{ - D("[ usb close ... ]\n"); - adb_mutex_lock(&usb_lock); - h->next->prev = h->prev; - h->prev->next = h->next; - h->prev = 0; - h->next = 0; - - adb_close(h->desc); - D("[ usb closed %p (fd = %d) ]\n", h, h->desc); - adb_mutex_unlock(&usb_lock); - - free(h); - return 0; -} - -static void register_device(const char *dev_name, - unsigned char ep_in, unsigned char ep_out, - int interface, - const char *serial, unsigned zero_mask) -{ - usb_handle* usb = 0; - int n = 0; - - /* Since Linux will not reassign the device ID (and dev_name) - ** as long as the device is open, we can add to the list here - ** once we open it and remove from the list when we're finally - ** closed and everything will work out fine. - ** - ** If we have a usb_handle on the list 'o handles with a matching - ** name, we have no further work to do. - */ - adb_mutex_lock(&usb_lock); - for(usb = handle_list.next; usb != &handle_list; usb = usb->next){ - if(!strcmp(usb->fname, dev_name)) { - adb_mutex_unlock(&usb_lock); - return; - } - } - adb_mutex_unlock(&usb_lock); - - D("[ usb located new device %s (%d/%d/%d) ]\n", - dev_name, ep_in, ep_out, interface); - usb = calloc(1, sizeof(usb_handle)); - strcpy(usb->fname, dev_name); - usb->ep_in = ep_in; - usb->ep_out = ep_out; - usb->zero_mask = zero_mask; - - adb_cond_init(&usb->notify, 0); - adb_mutex_init(&usb->lock, 0); - /* initialize mark to 1 so we don't get garbage collected after the device scan */ - usb->mark = 1; - usb->reaper_thread = 0; - - usb->desc = unix_open(usb->fname, O_RDWR); - if(usb->desc < 0) goto fail; - D("[ usb open %s fd = %d]\n", usb->fname, usb->desc); - n = ioctl(usb->desc, USBDEVFS_CLAIMINTERFACE, &interface); - if(n != 0) goto fail; - - /* add to the end of the active handles */ - adb_mutex_lock(&usb_lock); - usb->next = &handle_list; - usb->prev = handle_list.prev; - usb->prev->next = usb; - usb->next->prev = usb; - adb_mutex_unlock(&usb_lock); - - register_usb_transport(usb, serial); - return; - -fail: - D("[ usb open %s error=%d, err_str = %s]\n", - usb->fname, errno, strerror(errno)); - if(usb->desc >= 0) { - adb_close(usb->desc); - } - free(usb); -} - -void* device_poll_thread(void* unused) -{ - D("Created device thread\n"); - for(;;) { - /* XXX use inotify */ - find_usb_device("/dev/bus/usb", register_device); - kick_disconnected_devices(); - sleep(1); - } - return NULL; -} - -static void sigalrm_handler(int signo) -{ - // don't need to do anything here -} - -void usb_init() -{ - adb_thread_t tid; - struct sigaction actions; - - memset(&actions, 0, sizeof(actions)); - sigemptyset(&actions.sa_mask); - actions.sa_flags = 0; - actions.sa_handler = sigalrm_handler; - sigaction(SIGALRM,& actions, NULL); - - if(adb_thread_create(&tid, device_poll_thread, NULL)){ - fatal_errno("cannot create input thread"); - } -} - diff --git a/adb/usb_linux_client.c b/adb/usb_linux_client.c deleted file mode 100644 index 530bd04db55d6e62f3eabef6a6960a87bb612e65..0000000000000000000000000000000000000000 --- a/adb/usb_linux_client.c +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_USB -#include "adb.h" - - -struct usb_handle -{ - int fd; - adb_cond_t notify; - adb_mutex_t lock; -}; - -void usb_cleanup() -{ - // nothing to do here -} - -static void *usb_open_thread(void *x) -{ - struct usb_handle *usb = (struct usb_handle *)x; - int fd; - - while (1) { - // wait until the USB device needs opening - adb_mutex_lock(&usb->lock); - while (usb->fd != -1) - adb_cond_wait(&usb->notify, &usb->lock); - adb_mutex_unlock(&usb->lock); - - D("[ usb_thread - opening device ]\n"); - do { - /* XXX use inotify? */ - fd = unix_open("/dev/android_adb", O_RDWR); - if (fd < 0) { - // to support older kernels - fd = unix_open("/dev/android", O_RDWR); - } - if (fd < 0) { - adb_sleep_ms(1000); - } - } while (fd < 0); - D("[ opening device succeeded ]\n"); - - close_on_exec(fd); - usb->fd = fd; - - D("[ usb_thread - registering device ]\n"); - register_usb_transport(usb, 0); - } - - // never gets here - return 0; -} - -int usb_write(usb_handle *h, const void *data, int len) -{ - int n; - - D("[ write %d ]\n", len); - n = adb_write(h->fd, data, len); - if(n != len) { - D("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - D("[ done ]\n"); - return 0; -} - -int usb_read(usb_handle *h, void *data, int len) -{ - int n; - - D("[ read %d ]\n", len); - n = adb_read(h->fd, data, len); - if(n != len) { - D("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - return 0; -} - -void usb_init() -{ - usb_handle *h; - adb_thread_t tid; - int fd; - - h = calloc(1, sizeof(usb_handle)); - h->fd = -1; - adb_cond_init(&h->notify, 0); - adb_mutex_init(&h->lock, 0); - - // Open the file /dev/android_adb_enable to trigger - // the enabling of the adb USB function in the kernel. - // We never touch this file again - just leave it open - // indefinitely so the kernel will know when we are running - // and when we are not. - fd = unix_open("/dev/android_adb_enable", O_RDWR); - if (fd < 0) { - D("failed to open /dev/android_adb_enable\n"); - } else { - close_on_exec(fd); - } - - D("[ usb_init - starting thread ]\n"); - if(adb_thread_create(&tid, usb_open_thread, h)){ - fatal_errno("cannot create usb thread"); - } -} - -void usb_kick(usb_handle *h) -{ - D("usb_kick\n"); - adb_mutex_lock(&h->lock); - adb_close(h->fd); - h->fd = -1; - - // notify usb_open_thread that we are disconnected - adb_cond_signal(&h->notify); - adb_mutex_unlock(&h->lock); -} - -int usb_close(usb_handle *h) -{ - // nothing to do here - return 0; -} diff --git a/adb/usb_osx.c b/adb/usb_osx.c deleted file mode 100644 index 49e1eef5b6986ed81bbf08b213808e7c161032e4..0000000000000000000000000000000000000000 --- a/adb/usb_osx.c +++ /dev/null @@ -1,536 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <CoreFoundation/CoreFoundation.h> - -#include <IOKit/IOKitLib.h> -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/usb/IOUSBLib.h> -#include <IOKit/IOMessage.h> -#include <mach/mach_port.h> - -#include "sysdeps.h" - -#include <stdio.h> - -#define TRACE_TAG TRACE_USB -#include "adb.h" - -#define DBG D - -typedef struct { - int vid; - int pid; -} VendorProduct; - -#define kSupportedDeviceCount 4 -VendorProduct kSupportedDevices[kSupportedDeviceCount] = { - { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER }, - { VENDOR_ID_GOOGLE, PRODUCT_ID_SOONER_COMP }, - { VENDOR_ID_HTC, PRODUCT_ID_DREAM }, - { VENDOR_ID_HTC, PRODUCT_ID_DREAM_COMP }, -}; - -static IONotificationPortRef notificationPort = 0; -static io_iterator_t notificationIterators[kSupportedDeviceCount]; - -struct usb_handle -{ - UInt8 bulkIn; - UInt8 bulkOut; - IOUSBInterfaceInterface **interface; - io_object_t usbNotification; - unsigned int zero_mask; -}; - -static CFRunLoopRef currentRunLoop = 0; -static pthread_mutex_t start_lock; -static pthread_cond_t start_cond; - - -static void AndroidDeviceAdded(void *refCon, io_iterator_t iterator); -static void AndroidDeviceNotify(void *refCon, io_iterator_t iterator, natural_t messageType, void *messageArgument); -static usb_handle* FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product); - -static int -InitUSB() -{ - CFMutableDictionaryRef matchingDict; - CFRunLoopSourceRef runLoopSource; - SInt32 vendor, product; - int i; - - //* To set up asynchronous notifications, create a notification port and - //* add its run loop event source to the program's run loop - notificationPort = IONotificationPortCreate(kIOMasterPortDefault); - runLoopSource = IONotificationPortGetRunLoopSource(notificationPort); - CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopDefaultMode); - - memset(notificationIterators, 0, sizeof(notificationIterators)); - - //* loop through all supported vendor/product pairs - for (i = 0; i < kSupportedDeviceCount; i++) { - //* Create our matching dictionary to find the Android device - //* IOServiceAddMatchingNotification consumes the reference, so we do not need to release this - matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - - if (!matchingDict) { - DBG("ERR: Couldn't create USB matching dictionary.\n"); - return -1; - } - - //* Set up two matching dictionaries, one for each product ID we support. - //* This will cause the kernel to notify us only if the vendor and product IDs match. - vendor = kSupportedDevices[i].vid; - product = kSupportedDevices[i].pid; - CFDictionarySetValue(matchingDict, CFSTR(kUSBVendorID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &vendor)); - CFDictionarySetValue(matchingDict, CFSTR(kUSBProductID), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &product)); - - //* Now set up two notifications: one to be called when a raw device - //* is first matched by the I/O Kit and another to be called when the - //* device is terminated. - //* we need to do this with each matching dictionary. - IOServiceAddMatchingNotification( - notificationPort, - kIOFirstMatchNotification, - matchingDict, - AndroidDeviceAdded, - NULL, - ¬ificationIterators[i]); - - //* Iterate over set of matching devices to access already-present devices - //* and to arm the notification - AndroidDeviceAdded(NULL, notificationIterators[i]); - } - - return 0; -} - -static void -AndroidDeviceAdded(void *refCon, io_iterator_t iterator) -{ - kern_return_t kr; - io_service_t usbDevice; - IOCFPlugInInterface **plugInInterface = NULL; - IOUSBDeviceInterface182 **dev = NULL; - HRESULT result; - SInt32 score; - UInt16 vendor; - UInt16 product; - UInt8 serialIndex; - char serial[256]; - - while ((usbDevice = IOIteratorNext(iterator))) { - //* Create an intermediate plugin - kr = IOCreatePlugInInterfaceForService(usbDevice, - kIOUSBDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, &score); - - if ((kIOReturnSuccess != kr) || (!plugInInterface)) { - DBG("ERR: Unable to create a plug-in (%08x)\n", kr); - goto continue1; - } - - //* Now create the device interface - result = (*plugInInterface)->QueryInterface(plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev); - - if (result || !dev) { - DBG("ERR: Couldn't create a device interface (%08x)\n", (int) result); - goto continue2; - } - - //* Check the device to see if it's ours - kr = (*dev)->GetDeviceVendor(dev, &vendor); - kr = (*dev)->GetDeviceProduct(dev, &product); - kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); - - if (serialIndex > 0) { - IOUSBDevRequest req; - UInt16 buffer[256]; - - req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); - req.bRequest = kUSBRqGetDescriptor; - req.wValue = (kUSBStringDesc << 8) | serialIndex; - req.wIndex = 0; - req.pData = buffer; - req.wLength = sizeof(buffer); - kr = (*dev)->DeviceRequest(dev, &req); - - if (kr == kIOReturnSuccess && req.wLenDone > 0) { - int i, count; - - // skip first word, and copy the rest to the serial string, changing shorts to bytes. - count = (req.wLenDone - 1) / 2; - for (i = 0; i < count; i++) - serial[i] = buffer[i + 1]; - serial[i] = 0; - } - } - - usb_handle* handle = NULL; - - //* Open the device - kr = (*dev)->USBDeviceOpen(dev); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Could not open device: %08x\n", kr); - goto continue3; - } else { - //* Find an interface for the device - handle = FindDeviceInterface((IOUSBDeviceInterface**)dev, vendor, product); - } - - if (handle == NULL) { - DBG("ERR: Could not find device interface: %08x\n", kr); - (*dev)->USBDeviceClose(dev); - goto continue3; - } - - DBG("AndroidDeviceAdded calling register_usb_transport\n"); - register_usb_transport(handle, (serial[0] ? serial : NULL)); - - // Register for an interest notification of this device being removed. Pass the reference to our - // private data as the refCon for the notification. - kr = IOServiceAddInterestNotification(notificationPort, - usbDevice, - kIOGeneralInterest, - AndroidDeviceNotify, - handle, - &handle->usbNotification); - if (kIOReturnSuccess != kr) { - DBG("ERR: Unable to create interest notification (%08x)\n", kr); - } - -continue3: - (void)(*dev)->Release(dev); -continue2: - IODestroyPlugInInterface(plugInInterface); -continue1: - IOObjectRelease(usbDevice); - } -} - -static void -AndroidDeviceNotify(void *refCon, io_service_t service, natural_t messageType, void *messageArgument) -{ - usb_handle *handle = (usb_handle *)refCon; - - if (messageType == kIOMessageServiceIsTerminated) { - DBG("AndroidDeviceNotify\n"); - IOObjectRelease(handle->usbNotification); - usb_kick(handle); - } -} - -static usb_handle* -FindDeviceInterface(IOUSBDeviceInterface **dev, UInt16 vendor, UInt16 product) -{ - usb_handle* handle = NULL; - IOReturn kr; - IOUSBFindInterfaceRequest request; - io_iterator_t iterator; - io_service_t usbInterface; - IOCFPlugInInterface **plugInInterface; - IOUSBInterfaceInterface **interface = NULL; - HRESULT result; - SInt32 score; - UInt8 interfaceNumEndpoints, interfaceClass, interfaceSubClass, interfaceProtocol; - UInt8 endpoint, configuration; - - //* Placing the constant KIOUSBFindInterfaceDontCare into the following - //* fields of the IOUSBFindInterfaceRequest structure will allow us to - //* find all of the interfaces - request.bInterfaceClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - - //* SetConfiguration will kill an existing UMS connection, so let's not do this if not necessary. - configuration = 0; - (*dev)->GetConfiguration(dev, &configuration); - if (configuration != 1) - (*dev)->SetConfiguration(dev, 1); - - //* Get an iterator for the interfaces on the device - kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Couldn't create a device interface iterator: (%08x)\n", kr); - return NULL; - } - - while ((usbInterface = IOIteratorNext(iterator))) { - //* Create an intermediate plugin - kr = IOCreatePlugInInterfaceForService( - usbInterface, - kIOUSBInterfaceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); - - //* No longer need the usbInterface object now that we have the plugin - (void) IOObjectRelease(usbInterface); - - if ((kr != kIOReturnSuccess) || (!plugInInterface)) { - DBG("ERR: Unable to create plugin (%08x)\n", kr); - break; - } - - //* Now create the interface interface for the interface - result = (*plugInInterface)->QueryInterface( - plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), - (LPVOID) &interface); - - //* No longer need the intermediate plugin - (*plugInInterface)->Release(plugInInterface); - - if (result || !interface) { - DBG("ERR: Couldn't create interface interface: (%08x)\n", - (unsigned int) result); - break; - } - - //* Now open the interface. This will cause the pipes associated with - //* the endpoints in the interface descriptor to be instantiated - kr = (*interface)->USBInterfaceOpen(interface); - - if (kr != kIOReturnSuccess) - { - DBG("ERR: Could not open interface: (%08x)\n", kr); - (void) (*interface)->Release(interface); - //* continue so we can try the next interface - continue; - } - - //* Get the number of endpoints associated with this interface - kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); - - if (kr != kIOReturnSuccess) { - DBG("ERR: Unable to get number of endpoints: (%08x)\n", kr); - goto next_interface; - } - - //* Get interface class, subclass and protocol - if ((*interface)->GetInterfaceClass(interface, &interfaceClass) != kIOReturnSuccess || - (*interface)->GetInterfaceSubClass(interface, &interfaceSubClass) != kIOReturnSuccess || - (*interface)->GetInterfaceProtocol(interface, &interfaceProtocol) != kIOReturnSuccess) - { - DBG("ERR: Unable to get interface class, subclass and protocol\n"); - goto next_interface; - } - - //* check to make sure interface class, subclass and protocol match ADB - //* avoid opening mass storage endpoints - if (is_adb_interface(vendor, product, interfaceClass, interfaceSubClass, interfaceProtocol)) { - handle = calloc(1, sizeof(usb_handle)); - - //* Iterate over the endpoints for this interface and find the first - //* bulk in/out pipes available. These will be our read/write pipes. - for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { - UInt8 transferType; - UInt16 maxPacketSize; - UInt8 interval; - UInt8 number; - UInt8 direction; - - kr = (*interface)->GetPipeProperties(interface, endpoint, &direction, - &number, &transferType, &maxPacketSize, &interval); - - if (kIOReturnSuccess == kr) { - if (kUSBBulk != transferType) - continue; - - if (kUSBIn == direction) - handle->bulkIn = endpoint; - - if (kUSBOut == direction) - handle->bulkOut = endpoint; - - if (interfaceProtocol == 0x01) { - handle->zero_mask = maxPacketSize - 1; - } - - } else { - DBG("ERR: FindDeviceInterface - could not get pipe properties\n"); - } - } - - handle->interface = interface; - break; - } - -next_interface: - (*interface)->USBInterfaceClose(interface); - (*interface)->Release(interface); - } - - return handle; -} - - -void* RunLoopThread(void* unused) -{ - int i; - - InitUSB(); - - currentRunLoop = CFRunLoopGetCurrent(); - - // Signal the parent that we are running - adb_mutex_lock(&start_lock); - adb_cond_signal(&start_cond); - adb_mutex_unlock(&start_lock); - - CFRunLoopRun(); - currentRunLoop = 0; - - for (i = 0; i < kSupportedDeviceCount; i++) { - IOObjectRelease(notificationIterators[i]); - } - IONotificationPortDestroy(notificationPort); - - DBG("RunLoopThread done\n"); - return NULL; -} - - -static int initialized = 0; -void usb_init() -{ - if (!initialized) - { - adb_thread_t tid; - - adb_mutex_init(&start_lock, NULL); - adb_cond_init(&start_cond, NULL); - - if(adb_thread_create(&tid, RunLoopThread, NULL)) - fatal_errno("cannot create input thread"); - - // Wait for initialization to finish - adb_mutex_lock(&start_lock); - adb_cond_wait(&start_cond, &start_lock); - adb_mutex_unlock(&start_lock); - - adb_mutex_destroy(&start_lock); - adb_cond_destroy(&start_cond); - - initialized = 1; - } -} - -void usb_cleanup() -{ - DBG("usb_cleanup\n"); - close_usb_devices(); - if (currentRunLoop) - CFRunLoopStop(currentRunLoop); -} - -int usb_write(usb_handle *handle, const void *buf, int len) -{ - IOReturn result; - - if (!len) - return 0; - - if (!handle) - return -1; - - if (NULL == handle->interface) { - DBG("ERR: usb_write interface was null\n"); - return -1; - } - - if (0 == handle->bulkOut) { - DBG("ERR: bulkOut endpoint not assigned\n"); - return -1; - } - - result = - (*handle->interface)->WritePipe( - handle->interface, handle->bulkOut, (void *)buf, len); - - if ((result == 0) && (handle->zero_mask)) { - /* we need 0-markers and our transfer */ - if(!(len & handle->zero_mask)) { - result = - (*handle->interface)->WritePipe( - handle->interface, handle->bulkOut, (void *)buf, 0); - } - } - - if (0 == result) - return 0; - - DBG("ERR: usb_write failed with status %d\n", result); - return -1; -} - -int usb_read(usb_handle *handle, void *buf, int len) -{ - IOReturn result; - UInt32 numBytes = len; - - if (!len) { - return 0; - } - - if (!handle) { - return -1; - } - - if (NULL == handle->interface) { - DBG("ERR: usb_read interface was null\n"); - return -1; - } - - if (0 == handle->bulkIn) { - DBG("ERR: bulkIn endpoint not assigned\n"); - return -1; - } - - result = - (*handle->interface)->ReadPipe(handle->interface, - handle->bulkIn, buf, &numBytes); - - if (0 == result) - return 0; - else { - DBG("ERR: usb_read failed with status %d\n", result); - } - - return -1; -} - -int usb_close(usb_handle *handle) -{ - return 0; -} - -void usb_kick(usb_handle *handle) -{ - /* release the interface */ - if (handle->interface) - { - (*handle->interface)->USBInterfaceClose(handle->interface); - (*handle->interface)->Release(handle->interface); - handle->interface = 0; - } -} diff --git a/adb/usb_windows.c b/adb/usb_windows.c deleted file mode 100644 index 7ddaa0c185da56473b2ea451bf03f5ad5599729e..0000000000000000000000000000000000000000 --- a/adb/usb_windows.c +++ /dev/null @@ -1,513 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <windows.h> -#include <winerror.h> -#include <errno.h> -#include <usb100.h> -#include <adb_api.h> -#include <stdio.h> - -#include "sysdeps.h" - -#define TRACE_TAG TRACE_USB -#include "adb.h" - -/** Structure usb_handle describes our connection to the usb device via - AdbWinApi.dll. This structure is returned from usb_open() routine and - is expected in each subsequent call that is accessing the device. -*/ -struct usb_handle { - /// Previous entry in the list of opened usb handles - usb_handle *prev; - - /// Next entry in the list of opened usb handles - usb_handle *next; - - /// Handle to USB interface - ADBAPIHANDLE adb_interface; - - /// Handle to USB read pipe (endpoint) - ADBAPIHANDLE adb_read_pipe; - - /// Handle to USB write pipe (endpoint) - ADBAPIHANDLE adb_write_pipe; - - /// Interface name - char* interface_name; - - /// Mask for determining when to use zero length packets - unsigned zero_mask; -}; - -/// Class ID assigned to the device by androidusb.sys -static const GUID usb_class_id = ANDROID_USB_CLASS_ID; - -/// List of opened usb handles -static usb_handle handle_list = { - .prev = &handle_list, - .next = &handle_list, -}; - -/// Locker for the list of opened usb handles -ADB_MUTEX_DEFINE( usb_lock ); - -/// Checks if there is opened usb handle in handle_list for this device. -int known_device(const char* dev_name); - -/// Checks if there is opened usb handle in handle_list for this device. -/// usb_lock mutex must be held before calling this routine. -int known_device_locked(const char* dev_name); - -/// Registers opened usb handle (adds it to handle_list). -int register_new_device(usb_handle* handle); - -/// Checks if interface (device) matches certain criteria -int recognized_device(usb_handle* handle); - -/// Enumerates present and available interfaces (devices), opens new ones and -/// registers usb transport for them. -void find_devices(); - -/// Entry point for thread that polls (every second) for new usb interfaces. -/// This routine calls find_devices in infinite loop. -void* device_poll_thread(void* unused); - -/// Initializes this module -void usb_init(); - -/// Cleans up this module -void usb_cleanup(); - -/// Opens usb interface (device) by interface (device) name. -usb_handle* do_usb_open(const wchar_t* interface_name); - -/// Writes data to the opened usb handle -int usb_write(usb_handle* handle, const void* data, int len); - -/// Reads data using the opened usb handle -int usb_read(usb_handle *handle, void* data, int len); - -/// Cleans up opened usb handle -void usb_cleanup_handle(usb_handle* handle); - -/// Cleans up (but don't close) opened usb handle -void usb_kick(usb_handle* handle); - -/// Closes opened usb handle -int usb_close(usb_handle* handle); - -/// Gets interface (device) name for an opened usb handle -const char *usb_name(usb_handle* handle); - -int known_device_locked(const char* dev_name) { - usb_handle* usb; - - if (NULL != dev_name) { - // Iterate through the list looking for the name match. - for(usb = handle_list.next; usb != &handle_list; usb = usb->next) { - // In Windows names are not case sensetive! - if((NULL != usb->interface_name) && - (0 == stricmp(usb->interface_name, dev_name))) { - return 1; - } - } - } - - return 0; -} - -int known_device(const char* dev_name) { - int ret = 0; - - if (NULL != dev_name) { - adb_mutex_lock(&usb_lock); - ret = known_device_locked(dev_name); - adb_mutex_unlock(&usb_lock); - } - - return ret; -} - -int register_new_device(usb_handle* handle) { - if (NULL == handle) - return 0; - - adb_mutex_lock(&usb_lock); - - // Check if device is already in the list - if (known_device_locked(handle->interface_name)) { - adb_mutex_unlock(&usb_lock); - return 0; - } - - // Not in the list. Add this handle to the list. - handle->next = &handle_list; - handle->prev = handle_list.prev; - handle->prev->next = handle; - handle->next->prev = handle; - - adb_mutex_unlock(&usb_lock); - - return 1; -} - -void* device_poll_thread(void* unused) { - D("Created device thread\n"); - - while(1) { - find_devices(); - adb_sleep_ms(1000); - } - - return NULL; -} - -void usb_init() { - adb_thread_t tid; - - if(adb_thread_create(&tid, device_poll_thread, NULL)) { - fatal_errno("cannot create input thread"); - } -} - -void usb_cleanup() { -} - -usb_handle* do_usb_open(const wchar_t* interface_name) { - // Allocate our handle - usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); - if (NULL == ret) - return NULL; - - // Set linkers back to the handle - ret->next = ret; - ret->prev = ret; - - // Create interface. - ret->adb_interface = AdbCreateInterfaceByName(interface_name); - - if (NULL == ret->adb_interface) { - free(ret); - errno = GetLastError(); - return NULL; - } - - // Open read pipe (endpoint) - ret->adb_read_pipe = - AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, - AdbOpenAccessTypeReadWrite, - AdbOpenSharingModeReadWrite); - if (NULL != ret->adb_read_pipe) { - // Open write pipe (endpoint) - ret->adb_write_pipe = - AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, - AdbOpenAccessTypeReadWrite, - AdbOpenSharingModeReadWrite); - if (NULL != ret->adb_write_pipe) { - // Save interface name - unsigned long name_len = 0; - - // First get expected name length - AdbGetInterfaceName(ret->adb_interface, - NULL, - &name_len, - true); - if (0 != name_len) { - ret->interface_name = (char*)malloc(name_len); - - if (NULL != ret->interface_name) { - // Now save the name - if (AdbGetInterfaceName(ret->adb_interface, - ret->interface_name, - &name_len, - true)) { - // We're done at this point - return ret; - } - } else { - SetLastError(ERROR_OUTOFMEMORY); - } - } - } - } - - // Something went wrong. - errno = GetLastError(); - usb_cleanup_handle(ret); - free(ret); - SetLastError(errno); - - return NULL; -} - -int usb_write(usb_handle* handle, const void* data, int len) { - unsigned long time_out = 500 + len * 8; - unsigned long written = 0; - int ret; - - D("usb_write %d\n", len); - if (NULL != handle) { - // Perform write - ret = AdbWriteEndpointSync(handle->adb_write_pipe, - (void*)data, - (unsigned long)len, - &written, - time_out); - errno = GetLastError(); - - if (ret) { - // Make sure that we've written what we were asked to write - D("usb_write got: %ld, expected: %d\n", written, len); - if (written == (unsigned long)len) { - if(handle->zero_mask && (len & handle->zero_mask) == 0) { - // Send a zero length packet - AdbWriteEndpointSync(handle->adb_write_pipe, - (void*)data, - 0, - &written, - time_out); - } - return 0; - } - } else { - // assume ERROR_INVALID_HANDLE indicates we are disconnected - if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle); - } - } else { - D("usb_write NULL handle\n"); - SetLastError(ERROR_INVALID_HANDLE); - } - - D("usb_write failed: %d\n", errno); - - return -1; -} - -int usb_read(usb_handle *handle, void* data, int len) { - unsigned long time_out = 500 + len * 8; - unsigned long read = 0; - int ret; - - D("usb_read %d\n", len); - if (NULL != handle) { - while (len > 0) { - int xfer = (len > 4096) ? 4096 : len; - - ret = AdbReadEndpointSync(handle->adb_read_pipe, - (void*)data, - (unsigned long)xfer, - &read, - time_out); - errno = GetLastError(); - D("usb_write got: %ld, expected: %d, errno: %d\n", read, xfer, errno); - if (ret) { - data += read; - len -= read; - - if (len == 0) - return 0; - } else if (errno != ERROR_SEM_TIMEOUT) { - // assume ERROR_INVALID_HANDLE indicates we are disconnected - if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle); - break; - } - } - } else { - D("usb_read NULL handle\n"); - SetLastError(ERROR_INVALID_HANDLE); - } - - D("usb_read failed: %d\n", errno); - - return -1; -} - -void usb_cleanup_handle(usb_handle* handle) { - if (NULL != handle) { - if (NULL != handle->interface_name) - free(handle->interface_name); - if (NULL != handle->adb_write_pipe) - AdbCloseHandle(handle->adb_write_pipe); - if (NULL != handle->adb_read_pipe) - AdbCloseHandle(handle->adb_read_pipe); - if (NULL != handle->adb_interface) - AdbCloseHandle(handle->adb_interface); - - handle->interface_name = NULL; - handle->adb_write_pipe = NULL; - handle->adb_read_pipe = NULL; - handle->adb_interface = NULL; - } -} - -void usb_kick(usb_handle* handle) { - if (NULL != handle) { - adb_mutex_lock(&usb_lock); - - usb_cleanup_handle(handle); - - adb_mutex_unlock(&usb_lock); - } else { - SetLastError(ERROR_INVALID_HANDLE); - errno = ERROR_INVALID_HANDLE; - } -} - -int usb_close(usb_handle* handle) { - D("usb_close\n"); - - if (NULL != handle) { - // Remove handle from the list - adb_mutex_lock(&usb_lock); - - if ((handle->next != handle) && (handle->prev != handle)) { - handle->next->prev = handle->prev; - handle->prev->next = handle->next; - handle->prev = handle; - handle->next = handle; - } - - adb_mutex_unlock(&usb_lock); - - // Cleanup handle - usb_cleanup_handle(handle); - free(handle); - } - - return 0; -} - -const char *usb_name(usb_handle* handle) { - if (NULL == handle) { - SetLastError(ERROR_INVALID_HANDLE); - errno = ERROR_INVALID_HANDLE; - return NULL; - } - - return (const char*)handle->interface_name; -} - -int recognized_device(usb_handle* handle) { - if (NULL == handle) - return 0; - - // Check vendor and product id first - USB_DEVICE_DESCRIPTOR device_desc; - - if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, - &device_desc)) { - return 0; - } - - // Then check interface properties - USB_INTERFACE_DESCRIPTOR interf_desc; - - if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, - &interf_desc)) { - return 0; - } - - // Must have two endpoints - if (2 != interf_desc.bNumEndpoints) { - return 0; - } - - if (is_adb_interface(device_desc.idVendor, device_desc.idProduct, - interf_desc.bInterfaceClass, interf_desc.bInterfaceSubClass, interf_desc.bInterfaceProtocol)) { - - if(interf_desc.bInterfaceProtocol == 0x01) { - AdbEndpointInformation endpoint_info; - // assuming zero is a valid bulk endpoint ID - if (AdbGetEndpointInformation(handle->adb_interface, 0, &endpoint_info)) { - handle->zero_mask = endpoint_info.max_packet_size - 1; - } - } - - return 1; - } - - return 0; -} - -void find_devices() { - usb_handle* handle = NULL; - char entry_buffer[2048]; - char interf_name[2048]; - AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); - unsigned long entry_buffer_size = sizeof(entry_buffer); - char* copy_name; - - // Enumerate all present and active interfaces. - ADBAPIHANDLE enum_handle = - AdbEnumInterfaces(usb_class_id, true, true, true); - - if (NULL == enum_handle) - return; - - while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { - // TODO: FIXME - temp hack converting wchar_t into char. - // It would be better to change AdbNextInterface so it will return - // interface name as single char string. - const wchar_t* wchar_name = next_interface->device_name; - for(copy_name = interf_name; - L'\0' != *wchar_name; - wchar_name++, copy_name++) { - *copy_name = (char)(*wchar_name); - } - *copy_name = '\0'; - - // Lets see if we already have this device in the list - if (!known_device(interf_name)) { - // This seems to be a new device. Open it! - handle = do_usb_open(next_interface->device_name); - if (NULL != handle) { - // Lets see if this interface (device) belongs to us - if (recognized_device(handle)) { - D("adding a new device %s\n", interf_name); - char serial_number[512]; - unsigned long serial_number_len = sizeof(serial_number); - if (AdbGetSerialNumber(handle->adb_interface, - serial_number, - &serial_number_len, - true)) { - // Lets make sure that we don't duplicate this device - if (register_new_device(handle)) { - register_usb_transport(handle, serial_number); - } else { - D("register_new_device failed for %s\n", interf_name); - usb_cleanup_handle(handle); - free(handle); - } - } else { - D("cannot get serial number\n"); - usb_cleanup_handle(handle); - free(handle); - } - } else { - usb_cleanup_handle(handle); - free(handle); - } - } - } - - entry_buffer_size = sizeof(entry_buffer); - } - - AdbCloseHandle(enum_handle); -} diff --git a/adb/utils.c b/adb/utils.c deleted file mode 100644 index 91518bab669d31712970d1e9eb62b64c1aa6375d..0000000000000000000000000000000000000000 --- a/adb/utils.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "utils.h" -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - -char* -buff_addc (char* buff, char* buffEnd, int c) -{ - int avail = buffEnd - buff; - - if (avail <= 0) /* already in overflow mode */ - return buff; - - if (avail == 1) { /* overflowing, the last byte is reserved for zero */ - buff[0] = 0; - return buff + 1; - } - - buff[0] = (char) c; /* add char and terminating zero */ - buff[1] = 0; - return buff + 1; -} - -char* -buff_adds (char* buff, char* buffEnd, const char* s) -{ - int slen = strlen(s); - - return buff_addb(buff, buffEnd, s, slen); -} - -char* -buff_addb (char* buff, char* buffEnd, const void* data, int len) -{ - int avail = (buffEnd - buff); - - if (avail <= 0 || len <= 0) /* already overflowing */ - return buff; - - if (len > avail) - len = avail; - - memcpy(buff, data, len); - - buff += len; - - /* ensure there is a terminating zero */ - if (buff >= buffEnd) { /* overflow */ - buff[-1] = 0; - } else - buff[0] = 0; - - return buff; -} - -char* -buff_add (char* buff, char* buffEnd, const char* format, ... ) -{ - int avail; - - avail = (buffEnd - buff); - - if (avail > 0) { - va_list args; - int nn; - - va_start(args, format); - nn = vsnprintf( buff, avail, format, args); - va_end(args); - - if (nn < 0) { - /* some C libraries return -1 in case of overflow, - * but they will also do that if the format spec is - * invalid. We assume ADB is not buggy enough to - * trigger that last case. */ - nn = avail; - } - else if (nn > avail) { - nn = avail; - } - - buff += nn; - - /* ensure that there is a terminating zero */ - if (buff >= buffEnd) - buff[-1] = 0; - else - buff[0] = 0; - } - return buff; -} diff --git a/adb/utils.h b/adb/utils.h deleted file mode 100644 index f70ecd24dd8daebe8f87f94fc027ab3e720b4b81..0000000000000000000000000000000000000000 --- a/adb/utils.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef _ADB_UTILS_H -#define _ADB_UTILS_H - -/* bounded buffer functions */ - -/* all these functions are used to append data to a bounded buffer. - * - * after each operation, the buffer is guaranteed to be zero-terminated, - * even in the case of an overflow. they all return the new buffer position - * which allows one to use them in succession, only checking for overflows - * at the end. For example: - * - * BUFF_DECL(temp,p,end,1024); - * char* p; - * - * p = buff_addc(temp, end, '"'); - * p = buff_adds(temp, end, string); - * p = buff_addc(temp, end, '"'); - * - * if (p >= end) { - * overflow detected. note that 'temp' is - * zero-terminated for safety. - * } - * return strdup(temp); - */ - -/* tries to add a character to the buffer, in case of overflow - * this will only write a terminating zero and return buffEnd. - */ -char* buff_addc (char* buff, char* buffEnd, int c); - -/* tries to add a string to the buffer */ -char* buff_adds (char* buff, char* buffEnd, const char* s); - -/* tries to add a bytes to the buffer. the input can contain zero bytes, - * but a terminating zero will always be appended at the end anyway - */ -char* buff_addb (char* buff, char* buffEnd, const void* data, int len); - -/* tries to add a formatted string to a bounded buffer */ -char* buff_add (char* buff, char* buffEnd, const char* format, ... ); - -/* convenience macro used to define a bounded buffer, as well as - * a 'cursor' and 'end' variables all in one go. - * - * note: this doesn't place an initial terminating zero in the buffer, - * you need to use one of the buff_ functions for this. or simply - * do _cursor[0] = 0 manually. - */ -#define BUFF_DECL(_buff,_cursor,_end,_size) \ - char _buff[_size], *_cursor=_buff, *_end = _cursor + (_size) - -#endif /* _ADB_UTILS_H */ diff --git a/cpio/Android.mk b/cpio/Android.mk deleted file mode 100644 index 8d01852b0c925ae26dcc0d2634437459651a86cc..0000000000000000000000000000000000000000 --- a/cpio/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2005 The Android Open Source Project - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - mkbootfs.c - -LOCAL_MODULE := mkbootfs - -include $(BUILD_HOST_EXECUTABLE) - -$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) diff --git a/cpio/mkbootfs.c b/cpio/mkbootfs.c deleted file mode 100644 index f67233634ff7c156bd861d4cea3d5a307de4d0d5..0000000000000000000000000000000000000000 --- a/cpio/mkbootfs.c +++ /dev/null @@ -1,261 +0,0 @@ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> - -#include <stdarg.h> -#include <fcntl.h> - -#include <private/android_filesystem_config.h> - -/* NOTES -** -** - see buffer-format.txt from the linux kernel docs for -** an explanation of this file format -** - dotfiles are ignored -** - directories named 'root' are ignored -** - device notes, pipes, etc are not supported (error) -*/ - -void die(const char *why, ...) -{ - va_list ap; - - va_start(ap, why); - fprintf(stderr,"error: "); - vfprintf(stderr, why, ap); - fprintf(stderr,"\n"); - va_end(ap); - exit(1); -} - -static int verbose = 0; -static int total_size = 0; - -static void fix_stat(const char *path, struct stat *s) -{ - fs_config(path, S_ISDIR(s->st_mode), &s->st_uid, &s->st_gid, &s->st_mode); -} - -static void _eject(struct stat *s, char *out, int olen, char *data, unsigned datasize) -{ - // Nothing is special about this value, just picked something in the - // approximate range that was being used already, and avoiding small - // values which may be special. - static unsigned next_inode = 300000; - - while(total_size & 3) { - total_size++; - putchar(0); - } - - fix_stat(out, s); -// fprintf(stderr, "_eject %s: mode=0%o\n", out, s->st_mode); - - printf("%06x%08x%08x%08x%08x%08x%08x" - "%08x%08x%08x%08x%08x%08x%08x%s%c", - 0x070701, - next_inode++, // s.st_ino, - s->st_mode, - 0, // s.st_uid, - 0, // s.st_gid, - 1, // s.st_nlink, - 0, // s.st_mtime, - datasize, - 0, // volmajor - 0, // volminor - 0, // devmajor - 0, // devminor, - olen + 1, - 0, - out, - 0 - ); - - total_size += 6 + 8*13 + olen + 1; - - if(strlen(out) != olen) die("ACK!"); - - while(total_size & 3) { - total_size++; - putchar(0); - } - - if(datasize) { - fwrite(data, datasize, 1, stdout); - total_size += datasize; - } -} - -static void _eject_trailer() -{ - struct stat s; - memset(&s, 0, sizeof(s)); - _eject(&s, "TRAILER!!!", 10, 0, 0); - - while(total_size & 0xff) { - total_size++; - putchar(0); - } -} - -static void _archive(char *in, char *out, int ilen, int olen); - -static int compare(const void* a, const void* b) { - return strcmp(*(const char**)a, *(const char**)b); -} - -static void _archive_dir(char *in, char *out, int ilen, int olen) -{ - int i, t; - DIR *d; - struct dirent *de; - - if(verbose) { - fprintf(stderr,"_archive_dir('%s','%s',%d,%d)\n", - in, out, ilen, olen); - } - - d = opendir(in); - if(d == 0) die("cannot open directory '%s'", in); - - int size = 32; - int entries = 0; - char** names = malloc(size * sizeof(char*)); - if (names == NULL) { - fprintf(stderr, "failed to allocate dir names array (size %d)\n", size); - exit(1); - } - - while((de = readdir(d)) != 0){ - /* xxx: feature? maybe some dotfiles are okay */ - if(de->d_name[0] == '.') continue; - - /* xxx: hack. use a real exclude list */ - if(!strcmp(de->d_name, "root")) continue; - - if (entries >= size) { - size *= 2; - names = realloc(names, size * sizeof(char*)); - if (names == NULL) { - fprintf(stderr, "failed to reallocate dir names array (size %d)\n", - size); - exit(1); - } - } - names[entries] = strdup(de->d_name); - if (names[entries] == NULL) { - fprintf(stderr, "failed to strdup name \"%s\"\n", - de->d_name); - exit(1); - } - ++entries; - } - - qsort(names, entries, sizeof(char*), compare); - - for (i = 0; i < entries; ++i) { - t = strlen(names[i]); - in[ilen] = '/'; - memcpy(in + ilen + 1, names[i], t + 1); - - if(olen > 0) { - out[olen] = '/'; - memcpy(out + olen + 1, names[i], t + 1); - _archive(in, out, ilen + t + 1, olen + t + 1); - } else { - memcpy(out, names[i], t + 1); - _archive(in, out, ilen + t + 1, t); - } - - in[ilen] = 0; - out[olen] = 0; - - free(names[i]); - } - free(names); -} - -static void _archive(char *in, char *out, int ilen, int olen) -{ - struct stat s; - - if(verbose) { - fprintf(stderr,"_archive('%s','%s',%d,%d)\n", - in, out, ilen, olen); - } - - if(lstat(in, &s)) die("could not stat '%s'\n", in); - - if(S_ISREG(s.st_mode)){ - char *tmp; - int fd; - - fd = open(in, O_RDONLY); - if(fd < 0) die("cannot open '%s' for read", in); - - tmp = (char*) malloc(s.st_size); - if(tmp == 0) die("cannot allocate %d bytes", s.st_size); - - if(read(fd, tmp, s.st_size) != s.st_size) { - die("cannot read %d bytes", s.st_size); - } - - _eject(&s, out, olen, tmp, s.st_size); - - free(tmp); - close(fd); - } else if(S_ISDIR(s.st_mode)) { - _eject(&s, out, olen, 0, 0); - _archive_dir(in, out, ilen, olen); - } else if(S_ISLNK(s.st_mode)) { - char buf[1024]; - int size; - size = readlink(in, buf, 1024); - if(size < 0) die("cannot read symlink '%s'", in); - _eject(&s, out, olen, buf, size); - } else { - die("Unknown '%s' (mode %d)?\n", in, s.st_mode); - } -} - -void archive(const char *start, const char *prefix) -{ - char in[8192]; - char out[8192]; - - strcpy(in, start); - strcpy(out, prefix); - - _archive_dir(in, out, strlen(in), strlen(out)); -} - -int main(int argc, char *argv[]) -{ - argc--; - argv++; - - if(argc == 0) die("no directories to process?!"); - - while(argc-- > 0){ - char *x = strchr(*argv, '='); - if(x != 0) { - *x++ = 0; - } else { - x = ""; - } - - archive(*argv, x); - - argv++; - } - - _eject_trailer(); - - return 0; -} diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk deleted file mode 100644 index b22e1a81d757191f4d4e760e9060410abc4303a4..0000000000000000000000000000000000000000 --- a/debuggerd/Android.mk +++ /dev/null @@ -1,26 +0,0 @@ -# Copyright 2005 The Android Open Source Project - -ifeq ($(TARGET_ARCH),arm) - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= debuggerd.c getevent.c unwind-arm.c pr-support.c utility.c -LOCAL_CFLAGS := -Wall -LOCAL_MODULE := debuggerd - -LOCAL_STATIC_LIBRARIES := libcutils libc - -include $(BUILD_EXECUTABLE) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES := crasher.c -LOCAL_SRC_FILES += crashglue.S -LOCAL_MODULE := crasher -LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES) -LOCAL_MODULE_TAGS := eng -#LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_SHARED_LIBRARIES := libcutils libc -include $(BUILD_EXECUTABLE) - -endif # TARGET_ARCH == arm diff --git a/debuggerd/MODULE_LICENSE_APACHE2 b/debuggerd/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/debuggerd/NOTICE b/debuggerd/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/debuggerd/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/debuggerd/crasher.c b/debuggerd/crasher.c deleted file mode 100644 index f4a5a62bd84b08979bb2b5826c4bf5e7be74a275..0000000000000000000000000000000000000000 --- a/debuggerd/crasher.c +++ /dev/null @@ -1,105 +0,0 @@ - -//#include <cutils/misc.h> - -#include <unistd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sched.h> -#include <errno.h> - -#include <signal.h> -#include <sys/ptrace.h> -#include <sys/wait.h> -#include <sys/socket.h> - -#include <pthread.h> - -#include <cutils/sockets.h> - -void crash1(void); -void crashnostack(void); - -static void debuggerd_connect() -{ - char tmp[1]; - int s; - sprintf(tmp, "%d", gettid()); - s = socket_local_client("android:debuggerd", - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - if(s >= 0) { - read(s, tmp, 1); - close(s); - } -} - -void test_call1() -{ - *((int*) 32) = 1; -} - -void *test_thread(void *x) -{ - printf("crasher: thread pid=%d tid=%d\n", getpid(), gettid()); - - sleep(1); - test_call1(); - printf("goodbye\n"); - - return 0; -} - -void *noisy(void *x) -{ - char c = (unsigned) x; - for(;;) { - usleep(250*1000); - write(2, &c, 1); - if(c == 'C') *((unsigned*) 0) = 42; - } - return 0; -} - -int ctest() -{ - pthread_t thr; - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thr, &attr, noisy, (void*) 'A'); - pthread_create(&thr, &attr, noisy, (void*) 'B'); - pthread_create(&thr, &attr, noisy, (void*) 'C'); - for(;;) ; - return 0; -} - -int main(int argc, char **argv) -{ - pthread_t thr; - pthread_attr_t attr; - - fprintf(stderr,"crasher: " __TIME__ "!@\n"); - fprintf(stderr,"crasher: init pid=%d tid=%d\n", getpid(), gettid()); - - if(argc > 1) { - if(!strcmp(argv[1],"nostack")) crashnostack(); - if(!strcmp(argv[1],"ctest")) return ctest(); - if(!strcmp(argv[1],"exit")) exit(1); - if(!strcmp(argv[1],"abort")) maybeabort(); - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thr, &attr, test_thread, 0); - while(1) sleep(1); - } else { - crash1(); -// *((int*) 0) = 42; - } - - return 0; -} - -void maybeabort() -{ - if(time(0) != 42) abort(); -} diff --git a/debuggerd/crashglue.S b/debuggerd/crashglue.S deleted file mode 100644 index 888951b9c47335425ec738e531b47cb4d65aaa70..0000000000000000000000000000000000000000 --- a/debuggerd/crashglue.S +++ /dev/null @@ -1,28 +0,0 @@ -.globl crash1 -.globl crashnostack - -crash1: - ldr r0, =0xa5a50000 - ldr r1, =0xa5a50001 - ldr r2, =0xa5a50002 - ldr r3, =0xa5a50003 - ldr r4, =0xa5a50004 - ldr r5, =0xa5a50005 - ldr r6, =0xa5a50006 - ldr r7, =0xa5a50007 - ldr r8, =0xa5a50008 - ldr r9, =0xa5a50009 - ldr r10, =0xa5a50010 - ldr r11, =0xa5a50011 - ldr r12, =0xa5a50012 - - mov lr, #0 - ldr lr, [lr] - b . - - -crashnostack: - mov sp, #0 - mov r0, #0 - ldr r0, [r0] - b . \ No newline at end of file diff --git a/debuggerd/debuggerd.c b/debuggerd/debuggerd.c deleted file mode 100644 index 9394e1cacfbf2405226921a0abe8d74bc1f61c63..0000000000000000000000000000000000000000 --- a/debuggerd/debuggerd.c +++ /dev/null @@ -1,852 +0,0 @@ -/* system/debuggerd/debuggerd.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <signal.h> -#include <pthread.h> -#include <stdarg.h> -#include <fcntl.h> -#include <sys/types.h> -#include <dirent.h> - -#include <sys/ptrace.h> -#include <sys/wait.h> -#include <sys/exec_elf.h> -#include <sys/stat.h> - -#include <cutils/sockets.h> -#include <cutils/logd.h> -#include <cutils/sockets.h> -#include <cutils/properties.h> - -#include <linux/input.h> - -#include <private/android_filesystem_config.h> - -#include "utility.h" - -/* Main entry point to get the backtrace from the crashing process */ -extern int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map, - unsigned int sp_list[], - int *frame0_pc_sane, - bool at_fault); - -static char **process_name_ptr; - -static int logsocket = -1; - -#define ANDROID_LOG_INFO 4 - -/* Log information onto the tombstone */ -void _LOG(int tfd, bool in_tombstone_only, const char *fmt, ...) -{ - char buf[128]; - - va_list ap; - va_start(ap, fmt); - - if (tfd >= 0) { - int len; - vsnprintf(buf, sizeof(buf), fmt, ap); - len = strlen(buf); - if(tfd >= 0) write(tfd, buf, len); - } - - if (!in_tombstone_only) - __android_log_vprint(ANDROID_LOG_INFO, "DEBUG", fmt, ap); -} - -#define LOG(fmt...) _LOG(-1, 0, fmt) -#if 0 -#define XLOG(fmt...) _LOG(-1, 0, fmt) -#else -#define XLOG(fmt...) do {} while(0) -#endif - -// 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so -// 012345678901234567890123456789012345678901234567890123456789 -// 0 1 2 3 4 5 - -mapinfo *parse_maps_line(char *line) -{ - mapinfo *mi; - int len = strlen(line); - - if(len < 1) return 0; - line[--len] = 0; - - if(len < 50) return 0; - if(line[20] != 'x') return 0; - - mi = malloc(sizeof(mapinfo) + (len - 47)); - if(mi == 0) return 0; - - mi->start = strtoul(line, 0, 16); - mi->end = strtoul(line + 9, 0, 16); - /* To be filled in parse_exidx_info if the mapped section starts with - * elf_header - */ - mi->exidx_start = mi->exidx_end = 0; - mi->next = 0; - strcpy(mi->name, line + 49); - - return mi; -} - -void dump_build_info(int tfd) -{ - char fingerprint[PROPERTY_VALUE_MAX]; - - property_get("ro.build.fingerprint", fingerprint, "unknown"); - - _LOG(tfd, false, "Build fingerprint: '%s'\n", fingerprint); -} - - -void dump_stack_and_code(int tfd, int pid, mapinfo *map, - int unwind_depth, unsigned int sp_list[], - int frame0_pc_sane, bool at_fault) -{ - unsigned int sp, pc, p, end, data; - struct pt_regs r; - int sp_depth; - bool only_in_tombstone = !at_fault; - - if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return; - sp = r.ARM_sp; - pc = r.ARM_pc; - - /* Died because calling the weeds - dump - * the code around the PC in the next frame instead. - */ - if (frame0_pc_sane == 0) { - pc = r.ARM_lr; - } - - _LOG(tfd, true, "code%s:\n", frame0_pc_sane ? "" : " (around frame #01)"); - - end = p = pc & ~3; - p -= 16; - - /* Dump the code as: - * PC contents - * 00008d34 fffffcd0 4c0eb530 b0934a0e 1c05447c - * 00008d44 f7ff18a0 490ced94 68035860 d0012b00 - */ - while (p <= end) { - int i; - - _LOG(tfd, true, " %08x ", p); - for (i = 0; i < 4; i++) { - data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); - _LOG(tfd, true, " %08x", data); - p += 4; - } - _LOG(tfd, true, "\n", p); - } - - p = sp - 64; - p &= ~3; - if (unwind_depth != 0) { - if (unwind_depth < STACK_CONTENT_DEPTH) { - end = sp_list[unwind_depth-1]; - } - else { - end = sp_list[STACK_CONTENT_DEPTH-1]; - } - } - else { - end = sp | 0x000000ff; - end += 0xff; - } - - _LOG(tfd, only_in_tombstone, "stack:\n"); - - /* If the crash is due to PC == 0, there will be two frames that - * have identical SP value. - */ - if (sp_list[0] == sp_list[1]) { - sp_depth = 1; - } - else { - sp_depth = 0; - } - - while (p <= end) { - char *prompt; - char level[16]; - data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); - if (p == sp_list[sp_depth]) { - sprintf(level, "#%02d", sp_depth++); - prompt = level; - } - else { - prompt = " "; - } - - /* Print the stack content in the log for the first 3 frames. For the - * rest only print them in the tombstone file. - */ - _LOG(tfd, (sp_depth > 2) || only_in_tombstone, - "%s %08x %08x %s\n", prompt, p, data, - map_to_name(map, data, "")); - p += 4; - } - /* print another 64-byte of stack data after the last frame */ - - end = p+64; - while (p <= end) { - data = ptrace(PTRACE_PEEKTEXT, pid, (void*)p, NULL); - _LOG(tfd, (sp_depth > 2) || only_in_tombstone, - " %08x %08x %s\n", p, data, - map_to_name(map, data, "")); - p += 4; - } -} - -void dump_pc_and_lr(int tfd, int pid, mapinfo *map, int unwound_level, - bool at_fault) -{ - struct pt_regs r; - - if(ptrace(PTRACE_GETREGS, pid, 0, &r)) { - _LOG(tfd, !at_fault, "tid %d not responding!\n", pid); - return; - } - - if (unwound_level == 0) { - _LOG(tfd, !at_fault, " #%02d pc %08x %s\n", 0, r.ARM_pc, - map_to_name(map, r.ARM_pc, "<unknown>")); - } - _LOG(tfd, !at_fault, " #%02d lr %08x %s\n", 1, r.ARM_lr, - map_to_name(map, r.ARM_lr, "<unknown>")); -} - -void dump_registers(int tfd, int pid, bool at_fault) -{ - struct pt_regs r; - bool only_in_tombstone = !at_fault; - - if(ptrace(PTRACE_GETREGS, pid, 0, &r)) { - _LOG(tfd, only_in_tombstone, - "cannot get registers: %s\n", strerror(errno)); - return; - } - - _LOG(tfd, only_in_tombstone, " r0 %08x r1 %08x r2 %08x r3 %08x\n", - r.ARM_r0, r.ARM_r1, r.ARM_r2, r.ARM_r3); - _LOG(tfd, only_in_tombstone, " r4 %08x r5 %08x r6 %08x r7 %08x\n", - r.ARM_r4, r.ARM_r5, r.ARM_r6, r.ARM_r7); - _LOG(tfd, only_in_tombstone, " r8 %08x r9 %08x 10 %08x fp %08x\n", - r.ARM_r8, r.ARM_r9, r.ARM_r10, r.ARM_fp); - _LOG(tfd, only_in_tombstone, - " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", - r.ARM_ip, r.ARM_sp, r.ARM_lr, r.ARM_pc, r.ARM_cpsr); -} - -const char *get_signame(int sig) -{ - switch(sig) { - case SIGILL: return "SIGILL"; - case SIGABRT: return "SIGABRT"; - case SIGBUS: return "SIGBUS"; - case SIGFPE: return "SIGFPE"; - case SIGSEGV: return "SIGSEGV"; - case SIGSTKFLT: return "SIGSTKFLT"; - default: return "?"; - } -} - -void dump_fault_addr(int tfd, int pid, int sig) -{ - siginfo_t si; - - memset(&si, 0, sizeof(si)); - if(ptrace(PTRACE_GETSIGINFO, pid, 0, &si)){ - _LOG(tfd, false, "cannot get siginfo: %s\n", strerror(errno)); - } else { - _LOG(tfd, false, "signal %d (%s), fault addr %08x\n", - sig, get_signame(sig), si.si_addr); - } -} - -void dump_crash_banner(int tfd, unsigned pid, unsigned tid, int sig) -{ - char data[1024]; - char *x = 0; - FILE *fp; - - sprintf(data, "/proc/%d/cmdline", pid); - fp = fopen(data, "r"); - if(fp) { - x = fgets(data, 1024, fp); - fclose(fp); - } - - _LOG(tfd, false, - "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); - dump_build_info(tfd); - _LOG(tfd, false, "pid: %d, tid: %d >>> %s <<<\n", - pid, tid, x ? x : "UNKNOWN"); - - if(sig) dump_fault_addr(tfd, tid, sig); -} - -static void parse_exidx_info(mapinfo *milist, pid_t pid) -{ - mapinfo *mi; - for (mi = milist; mi != NULL; mi = mi->next) { - Elf32_Ehdr ehdr; - - memset(&ehdr, 0, sizeof(Elf32_Ehdr)); - /* Read in sizeof(Elf32_Ehdr) worth of data from the beginning of - * mapped section. - */ - get_remote_struct(pid, (void *) (mi->start), &ehdr, - sizeof(Elf32_Ehdr)); - /* Check if it has the matching magic words */ - if (IS_ELF(ehdr)) { - Elf32_Phdr phdr; - Elf32_Phdr *ptr; - int i; - - ptr = (Elf32_Phdr *) (mi->start + ehdr.e_phoff); - for (i = 0; i < ehdr.e_phnum; i++) { - /* Parse the program header */ - get_remote_struct(pid, (void *) ptr+i, &phdr, - sizeof(Elf32_Phdr)); - /* Found a EXIDX segment? */ - if (phdr.p_type == PT_ARM_EXIDX) { - mi->exidx_start = mi->start + phdr.p_offset; - mi->exidx_end = mi->exidx_start + phdr.p_filesz; - break; - } - } - } - } -} - -void dump_crash_report(int tfd, unsigned pid, unsigned tid, bool at_fault) -{ - char data[1024]; - FILE *fp; - mapinfo *milist = 0; - unsigned int sp_list[STACK_CONTENT_DEPTH]; - int stack_depth; - int frame0_pc_sane = 1; - - if (!at_fault) { - _LOG(tfd, true, - "--- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---\n"); - _LOG(tfd, true, "pid: %d, tid: %d\n", pid, tid); - } - - dump_registers(tfd, tid, at_fault); - - /* Clear stack pointer records */ - memset(sp_list, 0, sizeof(sp_list)); - - sprintf(data, "/proc/%d/maps", pid); - fp = fopen(data, "r"); - if(fp) { - while(fgets(data, 1024, fp)) { - mapinfo *mi = parse_maps_line(data); - if(mi) { - mi->next = milist; - milist = mi; - } - } - fclose(fp); - } - - parse_exidx_info(milist, tid); - - /* If stack unwinder fails, use the default solution to dump the stack - * content. - */ - stack_depth = unwind_backtrace_with_ptrace(tfd, tid, milist, sp_list, - &frame0_pc_sane, at_fault); - - /* The stack unwinder should at least unwind two levels of stack. If less - * level is seen we make sure at lease pc and lr are dumped. - */ - if (stack_depth < 2) { - dump_pc_and_lr(tfd, tid, milist, stack_depth, at_fault); - } - - dump_stack_and_code(tfd, tid, milist, stack_depth, sp_list, frame0_pc_sane, - at_fault); - - while(milist) { - mapinfo *next = milist->next; - free(milist); - milist = next; - } -} - -/* FIXME: unused: use it or lose it*/ -#if 0 -static -void start_gdbserver_vs(int pid, int port) -{ - pid_t p; - char *args[5]; - char commspec[16]; - char pidspec[16]; - - p = fork(); - if(p < 0) { - LOG("could not fork()\n"); - return; - } - - if(p == 0) { - sprintf(commspec, ":%d", port); - sprintf(pidspec, "%d", pid); - args[0] = "/system/bin/gdbserver"; - args[1] = commspec; - args[2] = "--attach"; - args[3] = pidspec; - args[4] = 0; - exit(execv(args[0], args)); - } else { - LOG("gdbserver pid=%d port=%d targetpid=%d\n", - p, port, pid); - - sleep(5); - } -} -#endif - -#define MAX_TOMBSTONES 10 - -#define typecheck(x,y) { \ - typeof(x) __dummy1; \ - typeof(y) __dummy2; \ - (void)(&__dummy1 == &__dummy2); } - -#define TOMBSTONE_DIR "/data/tombstones" - -/* - * find_and_open_tombstone - find an available tombstone slot, if any, of the - * form tombstone_XX where XX is 00 to MAX_TOMBSTONES-1, inclusive. If no - * file is available, we reuse the least-recently-modified file. - */ -static int find_and_open_tombstone(void) -{ - unsigned long mtime = ULONG_MAX; - struct stat sb; - char path[128]; - int fd, i, oldest = 0; - - /* - * XXX: Our stat.st_mtime isn't time_t. If it changes, as it probably ought - * to, our logic breaks. This check will generate a warning if that happens. - */ - typecheck(mtime, sb.st_mtime); - - /* - * In a single wolf-like pass, find an available slot and, in case none - * exist, find and record the least-recently-modified file. - */ - for (i = 0; i < MAX_TOMBSTONES; i++) { - snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", i); - - if (!stat(path, &sb)) { - if (sb.st_mtime < mtime) { - oldest = i; - mtime = sb.st_mtime; - } - continue; - } - if (errno != ENOENT) - continue; - - fd = open(path, O_CREAT | O_EXCL | O_WRONLY, 0600); - if (fd < 0) - continue; /* raced ? */ - - fchown(fd, AID_SYSTEM, AID_SYSTEM); - return fd; - } - - /* we didn't find an available file, so we clobber the oldest one */ - snprintf(path, sizeof(path), TOMBSTONE_DIR"/tombstone_%02d", oldest); - fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); - fchown(fd, AID_SYSTEM, AID_SYSTEM); - - return fd; -} - -/* Return true if some thread is not detached cleanly */ -static bool dump_sibling_thread_report(int tfd, unsigned pid, unsigned tid) -{ - char task_path[1024]; - - sprintf(task_path, "/proc/%d/task", pid); - DIR *d; - struct dirent *de; - int need_cleanup = 0; - - d = opendir(task_path); - /* Bail early if cannot open the task directory */ - if (d == NULL) { - XLOG("Cannot open /proc/%d/task\n", pid); - return false; - } - while ((de = readdir(d)) != NULL) { - unsigned new_tid; - /* Ignore "." and ".." */ - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; - new_tid = atoi(de->d_name); - /* The main thread at fault has been handled individually */ - if (new_tid == tid) - continue; - - /* Skip this thread if cannot ptrace it */ - if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) - continue; - - dump_crash_report(tfd, pid, new_tid, false); - need_cleanup |= ptrace(PTRACE_DETACH, new_tid, 0, 0); - } - closedir(d); - return need_cleanup != 0; -} - -/* Return true if some thread is not detached cleanly */ -static bool engrave_tombstone(unsigned pid, unsigned tid, int debug_uid, - int signal) -{ - int fd; - bool need_cleanup = false; - - mkdir(TOMBSTONE_DIR, 0755); - chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM); - - fd = find_and_open_tombstone(); - if (fd < 0) - return need_cleanup; - - dump_crash_banner(fd, pid, tid, signal); - dump_crash_report(fd, pid, tid, true); - /* - * If the user has requested to attach gdb, don't collect the per-thread - * information as it increases the chance to lose track of the process. - */ - if ((signed)pid > debug_uid) { - need_cleanup = dump_sibling_thread_report(fd, pid, tid); - } - - close(fd); - return need_cleanup; -} - -static int -write_string(const char* file, const char* string) -{ - int len; - int fd; - ssize_t amt; - fd = open(file, O_RDWR); - len = strlen(string); - if (fd < 0) - return -errno; - amt = write(fd, string, len); - close(fd); - return amt >= 0 ? 0 : -errno; -} - -static -void init_debug_led(void) -{ - // trout leds - write_string("/sys/class/leds/red/brightness", "0"); - write_string("/sys/class/leds/green/brightness", "0"); - write_string("/sys/class/leds/blue/brightness", "0"); - write_string("/sys/class/leds/red/device/blink", "0"); - // sardine leds - write_string("/sys/class/leds/left/cadence", "0,0"); -} - -static -void enable_debug_led(void) -{ - // trout leds - write_string("/sys/class/leds/red/brightness", "255"); - // sardine leds - write_string("/sys/class/leds/left/cadence", "1,0"); -} - -static -void disable_debug_led(void) -{ - // trout leds - write_string("/sys/class/leds/red/brightness", "0"); - // sardine leds - write_string("/sys/class/leds/left/cadence", "0,0"); -} - -extern int init_getevent(); -extern void uninit_getevent(); -extern int get_event(struct input_event* event, int timeout); - -static void wait_for_user_action(unsigned tid, struct ucred* cr) -{ - (void)tid; - /* First log a helpful message */ - LOG( "********************************************************\n" - "* process %d crashed. debuggerd waiting for gdbserver \n" - "* \n" - "* adb shell gdbserver :port --attach %d & \n" - "* \n" - "* and press the HOME key. \n" - "********************************************************\n", - cr->pid, cr->pid); - - /* wait for HOME key */ - if (init_getevent() == 0) { - int ms = 1200 / 10; - int dit = 1; - int dah = 3*dit; - int _ = -dit; - int ___ = 3*_; - int _______ = 7*_; - const signed char codes[] = { - dit,_,dit,_,dit,___,dah,_,dah,_,dah,___,dit,_,dit,_,dit,_______ - }; - size_t s = 0; - struct input_event e; - int home = 0; - init_debug_led(); - enable_debug_led(); - do { - int timeout = abs((int)(codes[s])) * ms; - int res = get_event(&e, timeout); - if (res == 0) { - if (e.type==EV_KEY && e.code==KEY_HOME && e.value==0) - home = 1; - } else if (res == 1) { - if (++s >= sizeof(codes)/sizeof(*codes)) - s = 0; - if (codes[s] > 0) { - enable_debug_led(); - } else { - disable_debug_led(); - } - } - } while (!home); - uninit_getevent(); - } - - /* don't forget to turn debug led off */ - disable_debug_led(); - - /* close filedescriptor */ - LOG("debuggerd resuming process %d", cr->pid); - } - -static void handle_crashing_process(int fd) -{ - char buf[64]; - struct stat s; - unsigned tid; - struct ucred cr; - int n, len, status; - int tid_attach_status = -1; - unsigned retry = 30; - bool need_cleanup = false; - - char value[PROPERTY_VALUE_MAX]; - property_get("debug.db.uid", value, "-1"); - int debug_uid = atoi(value); - - XLOG("handle_crashing_process(%d)\n", fd); - - len = sizeof(cr); - n = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len); - if(n != 0) { - LOG("cannot get credentials\n"); - goto done; - } - - XLOG("reading tid\n"); - fcntl(fd, F_SETFL, O_NONBLOCK); - while((n = read(fd, &tid, sizeof(unsigned))) != sizeof(unsigned)) { - if(errno == EINTR) continue; - if(errno == EWOULDBLOCK) { - if(retry-- > 0) { - usleep(100 * 1000); - continue; - } - LOG("timed out reading tid\n"); - goto done; - } - LOG("read failure? %s\n", strerror(errno)); - goto done; - } - - sprintf(buf,"/proc/%d/task/%d", cr.pid, tid); - if(stat(buf, &s)) { - LOG("tid %d does not exist in pid %d. ignorning debug request\n", - tid, cr.pid); - close(fd); - return; - } - - XLOG("BOOM: pid=%d uid=%d gid=%d tid=%d\n", cr.pid, cr.uid, cr.gid, tid); - - tid_attach_status = ptrace(PTRACE_ATTACH, tid, 0, 0); - if(tid_attach_status < 0) { - LOG("ptrace attach failed: %s\n", strerror(errno)); - goto done; - } - - close(fd); - fd = -1; - - for(;;) { - n = waitpid(tid, &status, __WALL); - - if(n < 0) { - if(errno == EAGAIN) continue; - LOG("waitpid failed: %s\n", strerror(errno)); - goto done; - } - - XLOG("waitpid: n=%d status=%08x\n", n, status); - - if(WIFSTOPPED(status)){ - n = WSTOPSIG(status); - switch(n) { - case SIGSTOP: - XLOG("stopped -- continuing\n"); - n = ptrace(PTRACE_CONT, tid, 0, 0); - if(n) { - LOG("ptrace failed: %s\n", strerror(errno)); - goto done; - } - continue; - - case SIGILL: - case SIGABRT: - case SIGBUS: - case SIGFPE: - case SIGSEGV: - case SIGSTKFLT: { - XLOG("stopped -- fatal signal\n"); - need_cleanup = engrave_tombstone(cr.pid, tid, debug_uid, n); - kill(tid, SIGSTOP); - goto done; - } - - default: - XLOG("stopped -- unexpected signal\n"); - goto done; - } - } else { - XLOG("unexpected waitpid response\n"); - goto done; - } - } - -done: - XLOG("detaching\n"); - - /* stop the process so we can debug */ - kill(cr.pid, SIGSTOP); - - /* - * If a thread has been attached by ptrace, make sure it is detached - * successfully otherwise we will get a zombie. - */ - if (tid_attach_status == 0) { - int detach_status; - /* detach so we can attach gdbserver */ - detach_status = ptrace(PTRACE_DETACH, tid, 0, 0); - need_cleanup |= (detach_status != 0); - } - - /* - * if debug.db.uid is set, its value indicates if we should wait - * for user action for the crashing process. - * in this case, we log a message and turn the debug LED on - * waiting for a gdb connection (for instance) - */ - - if ((signed)cr.uid <= debug_uid) { - wait_for_user_action(tid, &cr); - } - - /* resume stopped process (so it can crash in peace) */ - kill(cr.pid, SIGCONT); - - if (need_cleanup) { - LOG("debuggerd committing suicide to free the zombie!\n"); - kill(getpid(), SIGKILL); - } - - if(fd != -1) close(fd); -} - -int main(int argc, char **argv) -{ - int s; - struct sigaction act; - - process_name_ptr = argv; - - logsocket = socket_local_client("logd", - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_DGRAM); - if(logsocket < 0) { - logsocket = -1; - } else { - fcntl(logsocket, F_SETFD, FD_CLOEXEC); - } - - act.sa_handler = SIG_DFL; - sigemptyset(&act.sa_mask); - sigaddset(&act.sa_mask,SIGCHLD); - act.sa_flags = SA_NOCLDWAIT; - sigaction(SIGCHLD, &act, 0); - - s = socket_local_server("android:debuggerd", - ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM); - if(s < 0) return -1; - fcntl(s, F_SETFD, FD_CLOEXEC); - - LOG("debuggerd: " __DATE__ " " __TIME__ "\n"); - - for(;;) { - struct sockaddr addr; - socklen_t alen; - int fd; - - alen = sizeof(addr); - fd = accept(s, &addr, &alen); - if(fd < 0) continue; - - fcntl(fd, F_SETFD, FD_CLOEXEC); - - handle_crashing_process(fd); - } - return 0; -} diff --git a/debuggerd/getevent.c b/debuggerd/getevent.c deleted file mode 100644 index ebd070c0688848929fde3296280cce71c5797bf0..0000000000000000000000000000000000000000 --- a/debuggerd/getevent.c +++ /dev/null @@ -1,219 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <dirent.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/inotify.h> -#include <sys/limits.h> -#include <sys/poll.h> -#include <linux/input.h> -#include <errno.h> -#include <cutils/log.h> - -static struct pollfd *ufds; -static char **device_names; -static int nfds; - -static int open_device(const char *device) -{ - int version; - int fd; - struct pollfd *new_ufds; - char **new_device_names; - char name[80]; - char location[80]; - char idstr[80]; - struct input_id id; - - fd = open(device, O_RDWR); - if(fd < 0) { - return -1; - } - - if(ioctl(fd, EVIOCGVERSION, &version)) { - return -1; - } - if(ioctl(fd, EVIOCGID, &id)) { - return -1; - } - name[sizeof(name) - 1] = '\0'; - location[sizeof(location) - 1] = '\0'; - idstr[sizeof(idstr) - 1] = '\0'; - if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { - //fprintf(stderr, "could not get device name for %s, %s\n", device, strerror(errno)); - name[0] = '\0'; - } - if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) { - //fprintf(stderr, "could not get location for %s, %s\n", device, strerror(errno)); - location[0] = '\0'; - } - if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) { - //fprintf(stderr, "could not get idstring for %s, %s\n", device, strerror(errno)); - idstr[0] = '\0'; - } - - new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1)); - if(new_ufds == NULL) { - fprintf(stderr, "out of memory\n"); - return -1; - } - ufds = new_ufds; - new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1)); - if(new_device_names == NULL) { - fprintf(stderr, "out of memory\n"); - return -1; - } - device_names = new_device_names; - ufds[nfds].fd = fd; - ufds[nfds].events = POLLIN; - device_names[nfds] = strdup(device); - nfds++; - - return 0; -} - -int close_device(const char *device) -{ - int i; - for(i = 1; i < nfds; i++) { - if(strcmp(device_names[i], device) == 0) { - int count = nfds - i - 1; - free(device_names[i]); - memmove(device_names + i, device_names + i + 1, sizeof(device_names[0]) * count); - memmove(ufds + i, ufds + i + 1, sizeof(ufds[0]) * count); - nfds--; - return 0; - } - } - return -1; -} - -static int read_notify(const char *dirname, int nfd) -{ - int res; - char devname[PATH_MAX]; - char *filename; - char event_buf[512]; - int event_size; - int event_pos = 0; - struct inotify_event *event; - - res = read(nfd, event_buf, sizeof(event_buf)); - if(res < (int)sizeof(*event)) { - if(errno == EINTR) - return 0; - fprintf(stderr, "could not get event, %s\n", strerror(errno)); - return 1; - } - //printf("got %d bytes of event information\n", res); - - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - - while(res >= (int)sizeof(*event)) { - event = (struct inotify_event *)(event_buf + event_pos); - //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); - if(event->len) { - strcpy(filename, event->name); - if(event->mask & IN_CREATE) { - open_device(devname); - } - else { - close_device(devname); - } - } - event_size = sizeof(*event) + event->len; - res -= event_size; - event_pos += event_size; - } - return 0; -} - -static int scan_dir(const char *dirname) -{ - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - dir = opendir(dirname); - if(dir == NULL) - return -1; - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - while((de = readdir(dir))) { - if(de->d_name[0] == '.' && - (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) - continue; - strcpy(filename, de->d_name); - open_device(devname); - } - closedir(dir); - return 0; -} - -int init_getevent() -{ - int res; - const char *device_path = "/dev/input"; - - nfds = 1; - ufds = calloc(1, sizeof(ufds[0])); - ufds[0].fd = inotify_init(); - ufds[0].events = POLLIN; - - res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); - if(res < 0) { - return 1; - } - res = scan_dir(device_path); - if(res < 0) { - return 1; - } - return 0; -} - -void uninit_getevent() -{ - int i; - for(i = 0; i < nfds; i++) { - close(ufds[i].fd); - } - free(ufds); - ufds = 0; - nfds = 0; -} - -int get_event(struct input_event* event, int timeout) -{ - int res; - int i; - int pollres; - const char *device_path = "/dev/input"; - while(1) { - pollres = poll(ufds, nfds, timeout); - if (pollres == 0) { - return 1; - } - if(ufds[0].revents & POLLIN) { - read_notify(device_path, ufds[0].fd); - } - for(i = 1; i < nfds; i++) { - if(ufds[i].revents) { - if(ufds[i].revents & POLLIN) { - res = read(ufds[i].fd, event, sizeof(*event)); - if(res < (int)sizeof(event)) { - fprintf(stderr, "could not get event\n"); - return -1; - } - return 0; - } - } - } - } - return 0; -} diff --git a/debuggerd/pr-support.c b/debuggerd/pr-support.c deleted file mode 100644 index 358d9b77a4302724c85b0ce92e781edd42034b21..0000000000000000000000000000000000000000 --- a/debuggerd/pr-support.c +++ /dev/null @@ -1,345 +0,0 @@ -/* ARM EABI compliant unwinding routines - Copyright (C) 2004, 2005 Free Software Foundation, Inc. - Contributed by Paul Brook - - This file is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - In addition to the permissions in the GNU General Public License, the - Free Software Foundation gives you unlimited permission to link the - compiled version of this file into combinations with other programs, - and to distribute those combinations without any restriction coming - from the use of this file. (The General Public License restrictions - do apply in other respects; for example, they cover modification of - the file, and distribution when not linked into a combine - executable.) - - This file 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; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/**************************************************************************** - * The functions here are derived from gcc/config/arm/pr-support.c from the - * 4.3.x release. The main changes here involve the use of ptrace to retrieve - * memory/processor states from a remote process. - ****************************************************************************/ - -#include <sys/types.h> -#include <unwind.h> - -#include "utility.h" - -/* We add a prototype for abort here to avoid creating a dependency on - target headers. */ -extern void abort (void); - -/* Derived from _Unwind_VRS_Pop to use ptrace */ -extern _Unwind_VRS_Result -unwind_VRS_Pop_with_ptrace (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw discriminator, - _Unwind_VRS_DataRepresentation representation, - pid_t pid); - -typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ - -/* Misc constants. */ -#define R_IP 12 -#define R_SP 13 -#define R_LR 14 -#define R_PC 15 - -#define uint32_highbit (((_uw) 1) << 31) - -void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); - -/* Unwind descriptors. */ - -typedef struct -{ - _uw16 length; - _uw16 offset; -} EHT16; - -typedef struct -{ - _uw length; - _uw offset; -} EHT32; - -/* Personality routine helper functions. */ - -#define CODE_FINISH (0xb0) - -/* Derived from next_unwind_byte to use ptrace */ -/* Return the next byte of unwinding information, or CODE_FINISH if there is - no data remaining. */ -static inline _uw8 -next_unwind_byte_with_ptrace (__gnu_unwind_state * uws, pid_t pid) -{ - _uw8 b; - - if (uws->bytes_left == 0) - { - /* Load another word */ - if (uws->words_left == 0) - return CODE_FINISH; /* Nothing left. */ - uws->words_left--; - uws->data = get_remote_word(pid, uws->next); - uws->next++; - uws->bytes_left = 3; - } - else - uws->bytes_left--; - - /* Extract the most significant byte. */ - b = (uws->data >> 24) & 0xff; - uws->data <<= 8; - return b; -} - -/* Execute the unwinding instructions described by UWS. */ -_Unwind_Reason_Code -unwind_execute_with_ptrace(_Unwind_Context * context, __gnu_unwind_state * uws, - pid_t pid) -{ - _uw op; - int set_pc; - _uw reg; - - set_pc = 0; - for (;;) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == CODE_FINISH) - { - /* If we haven't already set pc then copy it from lr. */ - if (!set_pc) - { - _Unwind_VRS_Get (context, _UVRSC_CORE, R_LR, _UVRSD_UINT32, - ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_PC, _UVRSD_UINT32, - ®); - set_pc = 1; - } - /* Drop out of the loop. */ - break; - } - if ((op & 0x80) == 0) - { - /* vsp = vsp +- (imm6 << 2 + 4). */ - _uw offset; - - offset = ((op & 0x3f) << 2) + 4; - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - if (op & 0x40) - reg -= offset; - else - reg += offset; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - - if ((op & 0xf0) == 0x80) - { - op = (op << 8) | next_unwind_byte_with_ptrace (uws, pid); - if (op == 0x8000) - { - /* Refuse to unwind. */ - return _URC_FAILURE; - } - /* Pop r4-r15 under mask. */ - op = (op << 4) & 0xfff0; - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, _UVRSD_UINT32, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - if (op & (1 << R_PC)) - set_pc = 1; - continue; - } - if ((op & 0xf0) == 0x90) - { - op &= 0xf; - if (op == 13 || op == 15) - /* Reserved. */ - return _URC_FAILURE; - /* vsp = r[nnnn]. */ - _Unwind_VRS_Get (context, _UVRSC_CORE, op, _UVRSD_UINT32, ®); - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, ®); - continue; - } - if ((op & 0xf0) == 0xa0) - { - /* Pop r4-r[4+nnn], [lr]. */ - _uw mask; - - mask = (0xff0 >> (7 - (op & 7))) & 0xff0; - if (op & 8) - mask |= (1 << R_LR); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, mask, _UVRSD_UINT32, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xb0) - { - /* op == 0xb0 already handled. */ - if (op == 0xb1) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == 0 || ((op & 0xf0) != 0)) - /* Spare. */ - return _URC_FAILURE; - /* Pop r0-r4 under mask. */ - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_CORE, op, - _UVRSD_UINT32, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xb2) - { - /* vsp = vsp + 0x204 + (uleb128 << 2). */ - int shift; - - _Unwind_VRS_Get (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - op = next_unwind_byte_with_ptrace (uws, pid); - shift = 2; - while (op & 0x80) - { - reg += ((op & 0x7f) << shift); - shift += 7; - op = next_unwind_byte_with_ptrace (uws, pid); - } - reg += ((op & 0x7f) << shift) + 0x204; - _Unwind_VRS_Set (context, _UVRSC_CORE, R_SP, _UVRSD_UINT32, - ®); - continue; - } - if (op == 0xb3) - { - /* Pop VFP registers with fldmx. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xfc) == 0xb4) - { - /* Pop FPA E[4]-E[4+nn]. */ - op = 0x40000 | ((op & 3) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* op & 0xf8 == 0xb8. */ - /* Pop VFP D[8]-D[8+nnn] with fldmx. */ - op = 0x80000 | ((op & 7) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_VFPX, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf0) == 0xc0) - { - if (op == 0xc6) - { - /* Pop iWMMXt D registers. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, - _UVRSD_UINT64, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc7) - { - op = next_unwind_byte_with_ptrace (uws, pid); - if (op == 0 || (op & 0xf0) != 0) - /* Spare. */ - return _URC_FAILURE; - /* Pop iWMMXt wCGR{3,2,1,0} under mask. */ - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXC, op, - _UVRSD_UINT32, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if ((op & 0xf8) == 0xc0) - { - /* Pop iWMMXt wR[10]-wR[10+nnn]. */ - op = 0xa0000 | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_WMMXD, op, - _UVRSD_UINT64, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - if (op == 0xc8) - { -#ifndef __VFP_FP__ - /* Pop FPA registers. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_FPA, op, _UVRSD_FPAX, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#else - /* Pop VFPv3 registers D[16+ssss]-D[16+ssss+cccc] with vldm. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = (((op & 0xf0) + 16) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, - _UVRSD_DOUBLE, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; -#endif - } - if (op == 0xc9) - { - /* Pop VFP registers with fldmd. */ - op = next_unwind_byte_with_ptrace (uws, pid); - op = ((op & 0xf0) << 12) | ((op & 0xf) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, - _UVRSD_DOUBLE, pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - if ((op & 0xf8) == 0xd0) - { - /* Pop VFP D[8]-D[8+nnn] with fldmd. */ - op = 0x80000 | ((op & 7) + 1); - if (unwind_VRS_Pop_with_ptrace (context, _UVRSC_VFP, op, _UVRSD_DOUBLE, - pid) - != _UVRSR_OK) - return _URC_FAILURE; - continue; - } - /* Spare. */ - return _URC_FAILURE; - } - return _URC_OK; -} diff --git a/debuggerd/unwind-arm.c b/debuggerd/unwind-arm.c deleted file mode 100644 index 9642d2e4aeee9c931a70c77b828c6f968d630d02..0000000000000000000000000000000000000000 --- a/debuggerd/unwind-arm.c +++ /dev/null @@ -1,654 +0,0 @@ -/* ARM EABI compliant unwinding routines. - Copyright (C) 2004, 2005 Free Software Foundation, Inc. - Contributed by Paul Brook - - This file is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 2, or (at your option) any - later version. - - In addition to the permissions in the GNU General Public License, the - Free Software Foundation gives you unlimited permission to link the - compiled version of this file into combinations with other programs, - and to distribute those combinations without any restriction coming - from the use of this file. (The General Public License restrictions - do apply in other respects; for example, they cover modification of - the file, and distribution when not linked into a combine - executable.) - - This file 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; see the file COPYING. If not, write to - the Free Software Foundation, 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/**************************************************************************** - * The functions here are derived from gcc/config/arm/unwind-arm.c from the - * 4.3.x release. The main changes here involve the use of ptrace to retrieve - * memory/processor states from a remote process. - ****************************************************************************/ - -#include <cutils/logd.h> -#include <sys/ptrace.h> -#include <unwind.h> -#include "utility.h" - -typedef struct _ZSt9type_info type_info; /* This names C++ type_info type */ - -void __attribute__((weak)) __cxa_call_unexpected(_Unwind_Control_Block *ucbp); -bool __attribute__((weak)) __cxa_begin_cleanup(_Unwind_Control_Block *ucbp); -bool __attribute__((weak)) __cxa_type_match(_Unwind_Control_Block *ucbp, - const type_info *rttip, - bool is_reference, - void **matched_object); - -/* Misc constants. */ -#define R_IP 12 -#define R_SP 13 -#define R_LR 14 -#define R_PC 15 - -#define EXIDX_CANTUNWIND 1 -#define uint32_highbit (((_uw) 1) << 31) - -#define UCB_FORCED_STOP_FN(ucbp) ((ucbp)->unwinder_cache.reserved1) -#define UCB_PR_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved2) -#define UCB_SAVED_CALLSITE_ADDR(ucbp) ((ucbp)->unwinder_cache.reserved3) -#define UCB_FORCED_STOP_ARG(ucbp) ((ucbp)->unwinder_cache.reserved4) - -struct core_regs -{ - _uw r[16]; -}; - -/* We use normal integer types here to avoid the compiler generating - coprocessor instructions. */ -struct vfp_regs -{ - _uw64 d[16]; - _uw pad; -}; - -struct vfpv3_regs -{ - /* Always populated via VSTM, so no need for the "pad" field from - vfp_regs (which is used to store the format word for FSTMX). */ - _uw64 d[16]; -}; - -struct fpa_reg -{ - _uw w[3]; -}; - -struct fpa_regs -{ - struct fpa_reg f[8]; -}; - -struct wmmxd_regs -{ - _uw64 wd[16]; -}; - -struct wmmxc_regs -{ - _uw wc[4]; -}; - -/* Unwind descriptors. */ - -typedef struct -{ - _uw16 length; - _uw16 offset; -} EHT16; - -typedef struct -{ - _uw length; - _uw offset; -} EHT32; - -/* The ABI specifies that the unwind routines may only use core registers, - except when actually manipulating coprocessor state. This allows - us to write one implementation that works on all platforms by - demand-saving coprocessor registers. - - During unwinding we hold the coprocessor state in the actual hardware - registers and allocate demand-save areas for use during phase1 - unwinding. */ - -typedef struct -{ - /* The first fields must be the same as a phase2_vrs. */ - _uw demand_save_flags; - struct core_regs core; - _uw prev_sp; /* Only valid during forced unwinding. */ - struct vfp_regs vfp; - struct vfpv3_regs vfp_regs_16_to_31; - struct fpa_regs fpa; - struct wmmxd_regs wmmxd; - struct wmmxc_regs wmmxc; -} phase1_vrs; - -/* This must match the structure created by the assembly wrappers. */ -typedef struct -{ - _uw demand_save_flags; - struct core_regs core; -} phase2_vrs; - - -/* An exception index table entry. */ - -typedef struct __EIT_entry -{ - _uw fnoffset; - _uw content; -} __EIT_entry; - -/* Derived version to use ptrace */ -typedef _Unwind_Reason_Code (*personality_routine_with_ptrace) - (_Unwind_State, - _Unwind_Control_Block *, - _Unwind_Context *, - pid_t); - -/* Derived version to use ptrace */ -/* ABI defined personality routines. */ -static _Unwind_Reason_Code unwind_cpp_pr0_with_ptrace (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *, pid_t); -static _Unwind_Reason_Code unwind_cpp_pr1_with_ptrace (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *, pid_t); -static _Unwind_Reason_Code unwind_cpp_pr2_with_ptrace (_Unwind_State, - _Unwind_Control_Block *, _Unwind_Context *, pid_t); - -/* Execute the unwinding instructions described by UWS. */ -extern _Unwind_Reason_Code -unwind_execute_with_ptrace(_Unwind_Context * context, __gnu_unwind_state * uws, - pid_t pid); - -/* Derived version to use ptrace. Only handles core registers. Disregards - * FP and others. - */ -/* ABI defined function to pop registers off the stack. */ - -_Unwind_VRS_Result unwind_VRS_Pop_with_ptrace (_Unwind_Context *context, - _Unwind_VRS_RegClass regclass, - _uw discriminator, - _Unwind_VRS_DataRepresentation representation, - pid_t pid) -{ - phase1_vrs *vrs = (phase1_vrs *) context; - - switch (regclass) - { - case _UVRSC_CORE: - { - _uw *ptr; - _uw mask; - int i; - - if (representation != _UVRSD_UINT32) - return _UVRSR_FAILED; - - mask = discriminator & 0xffff; - ptr = (_uw *) vrs->core.r[R_SP]; - /* Pop the requested registers. */ - for (i = 0; i < 16; i++) - { - if (mask & (1 << i)) { - vrs->core.r[i] = get_remote_word(pid, ptr); - ptr++; - } - } - /* Writeback the stack pointer value if it wasn't restored. */ - if ((mask & (1 << R_SP)) == 0) - vrs->core.r[R_SP] = (_uw) ptr; - } - return _UVRSR_OK; - - default: - return _UVRSR_FAILED; - } -} - -/* Core unwinding functions. */ - -/* Calculate the address encoded by a 31-bit self-relative offset at address - P. */ -static inline _uw -selfrel_offset31 (const _uw *p, pid_t pid) -{ - _uw offset = get_remote_word(pid, (void*)p); - - //offset = *p; - /* Sign extend to 32 bits. */ - if (offset & (1 << 30)) - offset |= 1u << 31; - else - offset &= ~(1u << 31); - - return offset + (_uw) p; -} - - -/* Perform a binary search for RETURN_ADDRESS in TABLE. The table contains - NREC entries. */ - -static const __EIT_entry * -search_EIT_table (const __EIT_entry * table, int nrec, _uw return_address, - pid_t pid) -{ - _uw next_fn; - _uw this_fn; - int n, left, right; - - if (nrec == 0) - return (__EIT_entry *) 0; - - left = 0; - right = nrec - 1; - - while (1) - { - n = (left + right) / 2; - this_fn = selfrel_offset31 (&table[n].fnoffset, pid); - if (n != nrec - 1) - next_fn = selfrel_offset31 (&table[n + 1].fnoffset, pid) - 1; - else - next_fn = (_uw)0 - 1; - - if (return_address < this_fn) - { - if (n == left) - return (__EIT_entry *) 0; - right = n - 1; - } - else if (return_address <= next_fn) - return &table[n]; - else - left = n + 1; - } -} - -/* Find the exception index table eintry for the given address. */ -static const __EIT_entry* -get_eitp(_uw return_address, pid_t pid, mapinfo *map, mapinfo **containing_map) -{ - const __EIT_entry *eitp = NULL; - int nrec; - mapinfo *mi; - - /* The return address is the address of the instruction following the - call instruction (plus one in thumb mode). If this was the last - instruction in the function the address will lie in the following - function. Subtract 2 from the address so that it points within the call - instruction itself. */ - if (return_address >= 2) - return_address -= 2; - - for (mi = map; mi != NULL; mi = mi->next) { - if (return_address >= mi->start && return_address <= mi->end) break; - } - - if (mi) { - if (containing_map) *containing_map = mi; - eitp = (__EIT_entry *) mi->exidx_start; - nrec = (mi->exidx_end - mi->exidx_start)/sizeof(__EIT_entry); - eitp = search_EIT_table (eitp, nrec, return_address, pid); - } - return eitp; -} - -/* Find the exception index table eintry for the given address. - Fill in the relevant fields of the UCB. - Returns _URC_FAILURE if an error occurred, _URC_OK on success. */ - -static _Unwind_Reason_Code -get_eit_entry (_Unwind_Control_Block *ucbp, _uw return_address, pid_t pid, - mapinfo *map, mapinfo **containing_map) -{ - const __EIT_entry *eitp; - - eitp = get_eitp(return_address, pid, map, containing_map); - - if (!eitp) - { - UCB_PR_ADDR (ucbp) = 0; - return _URC_FAILURE; - } - ucbp->pr_cache.fnstart = selfrel_offset31 (&eitp->fnoffset, pid); - - _uw eitp_content = get_remote_word(pid, (void *)&eitp->content); - - /* Can this frame be unwound at all? */ - if (eitp_content == EXIDX_CANTUNWIND) - { - UCB_PR_ADDR (ucbp) = 0; - return _URC_END_OF_STACK; - } - - /* Obtain the address of the "real" __EHT_Header word. */ - - if (eitp_content & uint32_highbit) - { - /* It is immediate data. */ - ucbp->pr_cache.ehtp = (_Unwind_EHT_Header *)&eitp->content; - ucbp->pr_cache.additional = 1; - } - else - { - /* The low 31 bits of the content field are a self-relative - offset to an _Unwind_EHT_Entry structure. */ - ucbp->pr_cache.ehtp = - (_Unwind_EHT_Header *) selfrel_offset31 (&eitp->content, pid); - ucbp->pr_cache.additional = 0; - } - - /* Discover the personality routine address. */ - if (get_remote_word(pid, ucbp->pr_cache.ehtp) & (1u << 31)) - { - /* One of the predefined standard routines. */ - _uw idx = (get_remote_word(pid, ucbp->pr_cache.ehtp) >> 24) & 0xf; - if (idx == 0) - UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr0_with_ptrace; - else if (idx == 1) - UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr1_with_ptrace; - else if (idx == 2) - UCB_PR_ADDR (ucbp) = (_uw) &unwind_cpp_pr2_with_ptrace; - else - { /* Failed */ - UCB_PR_ADDR (ucbp) = 0; - return _URC_FAILURE; - } - } - else - { - /* Execute region offset to PR */ - UCB_PR_ADDR (ucbp) = selfrel_offset31 (ucbp->pr_cache.ehtp, pid); - /* Since we are unwinding the stack from a different process, it is - * impossible to execute the personality routine in debuggerd. Punt here. - */ - return _URC_FAILURE; - } - return _URC_OK; -} - -/* Print out the current call level, pc, and module name in the crash log */ -static _Unwind_Reason_Code log_function(_Unwind_Context *context, pid_t pid, - int tfd, - int stack_level, - mapinfo *map, - unsigned int sp_list[], - bool at_fault) -{ - _uw pc; - _uw rel_pc; - phase2_vrs *vrs = (phase2_vrs*) context; - const mapinfo *mi; - bool only_in_tombstone = !at_fault; - - if (stack_level < STACK_CONTENT_DEPTH) { - sp_list[stack_level] = vrs->core.r[R_SP]; - } - pc = vrs->core.r[R_PC]; - - // Top level frame - if (stack_level == 0) { - pc &= ~1; - } - // For deeper framers, rollback pc by one instruction - else { - pc = vrs->core.r[R_PC]; - /* Thumb mode - need to check whether the bl(x) has long offset or not. - * Examples: - * - * arm blx in the middle of thumb: - * 187ae: 2300 movs r3, #0 - * 187b0: f7fe ee1c blx 173ec - * 187b4: 2c00 cmp r4, #0 - * - * arm bl in the middle of thumb: - * 187d8: 1c20 adds r0, r4, #0 - * 187da: f136 fd15 bl 14f208 - * 187de: 2800 cmp r0, #0 - * - * pure thumb: - * 18894: 189b adds r3, r3, r2 - * 18896: 4798 blx r3 - * 18898: b001 add sp, #4 - */ - if (pc & 1) { - _uw prev_word; - pc = (pc & ~1); - prev_word = get_remote_word(pid, (void *) pc-4); - // Long offset - if ((prev_word & 0xf0000000) == 0xf0000000 && - (prev_word & 0x0000e000) == 0x0000e000) { - pc -= 4; - } - else { - pc -= 2; - } - } - else { - pc -= 4; - } - } - - /* We used to print the absolute PC in the back trace, and mask out the top - * 3 bits to guesstimate the offset in the .so file. This is not working for - * non-prelinked libraries since the starting offset may not be aligned on - * 1MB boundaries, and the library may be larger than 1MB. So for .so - * addresses we print the relative offset in back trace. - */ - rel_pc = pc; - mi = pc_to_mapinfo(map, pc, &rel_pc); - - _LOG(tfd, only_in_tombstone, - " #%02d pc %08x %s\n", stack_level, rel_pc, - mi ? mi->name : ""); - - return _URC_NO_REASON; -} - -/* Derived from __gnu_Unwind_Backtrace to use ptrace */ -/* Perform stack backtrace through unwind data. Return the level of stack it - * unwinds. - */ -int unwind_backtrace_with_ptrace(int tfd, pid_t pid, mapinfo *map, - unsigned int sp_list[], int *frame0_pc_sane, - bool at_fault) -{ - phase1_vrs saved_vrs; - _Unwind_Reason_Code code = _URC_OK; - struct pt_regs r; - int i; - int stack_level = 0; - - _Unwind_Control_Block ucb; - _Unwind_Control_Block *ucbp = &ucb; - - if(ptrace(PTRACE_GETREGS, pid, 0, &r)) return 0; - - for (i = 0; i < 16; i++) { - saved_vrs.core.r[i] = r.uregs[i]; - /* - _LOG(tfd, "r[%d] = 0x%x\n", i, saved_vrs.core.r[i]); - */ - } - - /* Set demand-save flags. */ - saved_vrs.demand_save_flags = ~(_uw) 0; - - /* - * If the app crashes because of calling the weeds, we cannot pass the PC - * to the usual unwinding code as the EXIDX mapping will fail. - * Instead, we simply print out the 0 as the top frame, and resume the - * unwinding process with the value stored in LR. - */ - if (get_eitp(saved_vrs.core.r[R_PC], pid, map, NULL) == NULL) { - *frame0_pc_sane = 0; - log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level, - map, sp_list, at_fault); - saved_vrs.core.r[R_PC] = saved_vrs.core.r[R_LR]; - stack_level++; - } - - do { - mapinfo *this_map = NULL; - /* Find the entry for this routine. */ - if (get_eit_entry(ucbp, saved_vrs.core.r[R_PC], pid, map, &this_map) - != _URC_OK) { - /* Uncomment the code below to study why the unwinder failed */ -#if 0 - /* Shed more debugging info for stack unwinder improvement */ - if (this_map) { - _LOG(tfd, 1, - "Relative PC=%#x from %s not contained in EXIDX\n", - saved_vrs.core.r[R_PC] - this_map->start, this_map->name); - } - _LOG(tfd, 1, "PC=%#x SP=%#x\n", - saved_vrs.core.r[R_PC], saved_vrs.core.r[R_SP]); -#endif - code = _URC_FAILURE; - break; - } - - /* The dwarf unwinder assumes the context structure holds things - like the function and LSDA pointers. The ARM implementation - caches these in the exception header (UCB). To avoid - rewriting everything we make the virtual IP register point at - the UCB. */ - _Unwind_SetGR((_Unwind_Context *)&saved_vrs, 12, (_Unwind_Ptr) ucbp); - - /* Call log function. */ - if (log_function ((_Unwind_Context *) &saved_vrs, pid, tfd, stack_level, - map, sp_list, at_fault) != _URC_NO_REASON) { - code = _URC_FAILURE; - break; - } - stack_level++; - - /* Call the pr to decide what to do. */ - code = ((personality_routine_with_ptrace) UCB_PR_ADDR (ucbp))( - _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND, ucbp, - (void *) &saved_vrs, pid); - /* - * In theory the unwinding process will stop when the end of stack is - * reached or there is no unwinding information for the code address. - * To add another level of guarantee that the unwinding process - * will terminate we will stop it when the STACK_CONTENT_DEPTH is reached. - */ - } while (code != _URC_END_OF_STACK && code != _URC_FAILURE && - stack_level < STACK_CONTENT_DEPTH); - return stack_level; -} - - -/* Derived version to use ptrace */ -/* Common implementation for ARM ABI defined personality routines. - ID is the index of the personality routine, other arguments are as defined - by __aeabi_unwind_cpp_pr{0,1,2}. */ - -static _Unwind_Reason_Code -unwind_pr_common_with_ptrace (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context, - int id, - pid_t pid) -{ - __gnu_unwind_state uws; - _uw *data; - int phase2_call_unexpected_after_unwind = 0; - - state &= _US_ACTION_MASK; - - data = (_uw *) ucbp->pr_cache.ehtp; - uws.data = get_remote_word(pid, data); - data++; - uws.next = data; - if (id == 0) - { - uws.data <<= 8; - uws.words_left = 0; - uws.bytes_left = 3; - } - else - { - uws.words_left = (uws.data >> 16) & 0xff; - uws.data <<= 16; - uws.bytes_left = 2; - data += uws.words_left; - } - - /* Restore the saved pointer. */ - if (state == _US_UNWIND_FRAME_RESUME) - data = (_uw *) ucbp->cleanup_cache.bitpattern[0]; - - if ((ucbp->pr_cache.additional & 1) == 0) - { - /* Process descriptors. */ - while (get_remote_word(pid, data)) { - /********************************************************************** - * The original code here seems to deal with exceptions that are not - * applicable in our toolchain, thus there is no way to test it for now. - * Instead of leaving it here and causing potential instability in - * debuggerd, we'd better punt here and leave the stack unwound. - * In the future when we discover cases where the stack should be unwound - * further but is not, we can revisit the code here. - **********************************************************************/ - return _URC_FAILURE; - } - /* Finished processing this descriptor. */ - } - - if (unwind_execute_with_ptrace (context, &uws, pid) != _URC_OK) - return _URC_FAILURE; - - if (phase2_call_unexpected_after_unwind) - { - /* Enter __cxa_unexpected as if called from the call site. */ - _Unwind_SetGR (context, R_LR, _Unwind_GetGR (context, R_PC)); - _Unwind_SetGR (context, R_PC, (_uw) &__cxa_call_unexpected); - return _URC_INSTALL_CONTEXT; - } - - return _URC_CONTINUE_UNWIND; -} - - -/* ABI defined personality routine entry points. */ - -static _Unwind_Reason_Code -unwind_cpp_pr0_with_ptrace (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context, - pid_t pid) -{ - return unwind_pr_common_with_ptrace (state, ucbp, context, 0, pid); -} - -static _Unwind_Reason_Code -unwind_cpp_pr1_with_ptrace (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context, - pid_t pid) -{ - return unwind_pr_common_with_ptrace (state, ucbp, context, 1, pid); -} - -static _Unwind_Reason_Code -unwind_cpp_pr2_with_ptrace (_Unwind_State state, - _Unwind_Control_Block *ucbp, - _Unwind_Context *context, - pid_t pid) -{ - return unwind_pr_common_with_ptrace (state, ucbp, context, 2, pid); -} diff --git a/debuggerd/utility.c b/debuggerd/utility.c deleted file mode 100644 index 8f3931c1fdcb867b286a4cdf3a61be7398200c02..0000000000000000000000000000000000000000 --- a/debuggerd/utility.c +++ /dev/null @@ -1,83 +0,0 @@ -/* system/debuggerd/utility.c -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <sys/ptrace.h> -#include <sys/exec_elf.h> -#include <assert.h> -#include <string.h> -#include <errno.h> - -#include "utility.h" - -/* Get a word from pid using ptrace. The result is the return value. */ -int get_remote_word(int pid, void *src) -{ - return ptrace(PTRACE_PEEKTEXT, pid, src, NULL); -} - - -/* Handy routine to read aggregated data from pid using ptrace. The read - * values are written to the dest locations directly. - */ -void get_remote_struct(int pid, void *src, void *dst, size_t size) -{ - unsigned int i; - - for (i = 0; i+4 <= size; i+=4) { - *(int *)(dst+i) = ptrace(PTRACE_PEEKTEXT, pid, src+i, NULL); - } - - if (i < size) { - int val; - - assert((size - i) < 4); - val = ptrace(PTRACE_PEEKTEXT, pid, src+i, NULL); - while (i < size) { - ((unsigned char *)dst)[i] = val & 0xff; - i++; - val >>= 8; - } - } -} - -/* Map a pc address to the name of the containing ELF file */ -const char *map_to_name(mapinfo *mi, unsigned pc, const char* def) -{ - while(mi) { - if((pc >= mi->start) && (pc < mi->end)){ - return mi->name; - } - mi = mi->next; - } - return def; -} - -/* Find the containing map info for the pc */ -const mapinfo *pc_to_mapinfo(mapinfo *mi, unsigned pc, unsigned *rel_pc) -{ - while(mi) { - if((pc >= mi->start) && (pc < mi->end)){ - // Only calculate the relative offset for shared libraries - if (strstr(mi->name, ".so")) { - *rel_pc = pc - mi->start; - } - return mi; - } - mi = mi->next; - } - return NULL; -} diff --git a/debuggerd/utility.h b/debuggerd/utility.h deleted file mode 100644 index 49f59518ec7550b94f9274759055189a2406ac2f..0000000000000000000000000000000000000000 --- a/debuggerd/utility.h +++ /dev/null @@ -1,56 +0,0 @@ -/* system/debuggerd/utility.h -** -** Copyright 2008, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef __utility_h -#define __utility_h - -#include <stddef.h> -#include <stdbool.h> - -#ifndef PT_ARM_EXIDX -#define PT_ARM_EXIDX 0x70000001 /* .ARM.exidx segment */ -#endif - -#define STACK_CONTENT_DEPTH 32 - -typedef struct mapinfo { - struct mapinfo *next; - unsigned start; - unsigned end; - unsigned exidx_start; - unsigned exidx_end; - char name[]; -} mapinfo; - -/* Get a word from pid using ptrace. The result is the return value. */ -extern int get_remote_word(int pid, void *src); - -/* Handy routine to read aggregated data from pid using ptrace. The read - * values are written to the dest locations directly. - */ -extern void get_remote_struct(int pid, void *src, void *dst, size_t size); - -/* Find the containing map for the pc */ -const mapinfo *pc_to_mapinfo (mapinfo *mi, unsigned pc, unsigned *rel_pc); - -/* Map a pc address to the name of the containing ELF file */ -const char *map_to_name(mapinfo *mi, unsigned pc, const char* def); - -/* Log information onto the tombstone */ -extern void _LOG(int tfd, bool in_tombstone_only, const char *fmt, ...); - -#endif diff --git a/fastboot/Android.mk b/fastboot/Android.mk deleted file mode 100644 index 7a9d35f28569466301f8eb2d6867be073de63b83..0000000000000000000000000000000000000000 --- a/fastboot/Android.mk +++ /dev/null @@ -1,57 +0,0 @@ -# Copyright (C) 2007 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg -LOCAL_SRC_FILES := protocol.c engine.c bootimg.c fastboot.c -LOCAL_MODULE := fastboot - -ifeq ($(HOST_OS),linux) - LOCAL_SRC_FILES += usb_linux.c util_linux.c -endif - -ifeq ($(HOST_OS),darwin) - LOCAL_SRC_FILES += usb_osx.c util_osx.c - LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit \ - -framework Carbon -endif - -ifeq ($(HOST_OS),windows) - LOCAL_SRC_FILES += usb_windows.c util_windows.c - EXTRA_STATIC_LIBS := AdbWinApi - LOCAL_C_INCLUDES += /usr/include/w32api/ddk development/host/windows/usb/api - ifeq ($(strip $(USE_CYGWIN)),) - LOCAL_LDLIBS += -lws2_32 - USE_SYSDEPS_WIN32 := 1 - endif -endif - -LOCAL_STATIC_LIBRARIES := $(EXTRA_STATIC_LIBS) libzipfile libunz - -include $(BUILD_HOST_EXECUTABLE) -$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) - -ifeq ($(HOST_OS),linux) -include $(CLEAR_VARS) -LOCAL_SRC_FILES := usbtest.c usb_linux.c -LOCAL_MODULE := usbtest -include $(BUILD_HOST_EXECUTABLE) -endif - -ifeq ($(HOST_OS),windows) -$(LOCAL_INSTALLED_MODULE): $(HOST_OUT_EXECUTABLES)/AdbWinApi.dll -endif diff --git a/fastboot/bootimg.c b/fastboot/bootimg.c deleted file mode 100644 index 1d77b3c4320bf44925fadd877c372f93959713c8..0000000000000000000000000000000000000000 --- a/fastboot/bootimg.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <bootimg.h> - -void bootimg_set_cmdline(boot_img_hdr *h, const char *cmdline) -{ - strcpy((char*) h->cmdline, cmdline); -} - -boot_img_hdr *mkbootimg(void *kernel, unsigned kernel_size, - void *ramdisk, unsigned ramdisk_size, - void *second, unsigned second_size, - unsigned page_size, - unsigned *bootimg_size) -{ - unsigned kernel_actual; - unsigned ramdisk_actual; - unsigned second_actual; - unsigned page_mask; - boot_img_hdr *hdr; - - page_mask = page_size - 1; - - kernel_actual = (kernel_size + page_mask) & (~page_mask); - ramdisk_actual = (ramdisk_size + page_mask) & (~page_mask); - second_actual = (second_size + page_mask) & (~page_mask); - - *bootimg_size = page_size + kernel_actual + ramdisk_actual + second_actual; - - hdr = calloc(*bootimg_size, 1); - - if(hdr == 0) { - return hdr; - } - - memcpy(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); - - hdr->kernel_size = kernel_size; - hdr->kernel_addr = 0x10008000; - hdr->ramdisk_size = ramdisk_size; - hdr->ramdisk_addr = 0x11000000; - hdr->second_size = second_size; - hdr->second_addr = 0x10F00000; - - hdr->tags_addr = 0x10000100; - hdr->page_size = page_size; - - memcpy(hdr->magic + page_size, - kernel, kernel_size); - memcpy(hdr->magic + page_size + kernel_actual, - ramdisk, ramdisk_size); - memcpy(hdr->magic + page_size + kernel_actual + ramdisk_actual, - second, second_size); - return hdr; -} diff --git a/fastboot/engine.c b/fastboot/engine.c deleted file mode 100644 index 4c7e197fd825d2dc12ef1e8452e3bd96f4d1280a..0000000000000000000000000000000000000000 --- a/fastboot/engine.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> - -#include "fastboot.h" - -char *mkmsg(const char *fmt, ...) -{ - char buf[256]; - char *s; - va_list ap; - - va_start(ap, fmt); - vsprintf(buf, fmt, ap); - va_end(ap); - - s = strdup(buf); - if (s == 0) die("out of memory"); - return s; -} - -#define OP_DOWNLOAD 1 -#define OP_COMMAND 2 -#define OP_QUERY 3 -#define OP_NOTICE 4 - -typedef struct Action Action; - -struct Action -{ - unsigned op; - Action *next; - - char cmd[64]; - void *data; - unsigned size; - - const char *msg; - int (*func)(Action *a, int status, char *resp); -}; - -static Action *action_list = 0; -static Action *action_last = 0; - -static int cb_default(Action *a, int status, char *resp) -{ - if (status) { - fprintf(stderr,"FAILED (%s)\n", resp); - } else { - fprintf(stderr,"OKAY\n"); - } - return status; -} - -static Action *queue_action(unsigned op, const char *fmt, ...) -{ - Action *a; - va_list ap; - - a = calloc(1, sizeof(Action)); - if (a == 0) die("out of memory"); - - va_start(ap, fmt); - vsprintf(a->cmd, fmt, ap); - va_end(ap); - - if (action_last) { - action_last->next = a; - } else { - action_list = a; - } - action_last = a; - a->op = op; - a->func = cb_default; - return a; -} - -void fb_queue_erase(const char *ptn) -{ - Action *a; - a = queue_action(OP_COMMAND, "erase:%s", ptn); - a->msg = mkmsg("erasing '%s'", ptn); -} - -void fb_queue_flash(const char *ptn, void *data, unsigned sz) -{ - Action *a; - - a = queue_action(OP_DOWNLOAD, ""); - a->data = data; - a->size = sz; - a->msg = mkmsg("sending '%s' (%d KB)", ptn, sz / 1024); - - a = queue_action(OP_COMMAND, "flash:%s", ptn); - a->msg = mkmsg("writing '%s'", ptn); -} - -static int match(char *str, const char **value, unsigned count) -{ - const char *val; - unsigned n; - int len; - - for (n = 0; n < count; n++) { - const char *val = value[n]; - int len = strlen(val); - int match; - - if ((len > 1) && (val[len-1] == '*')) { - len--; - match = !strncmp(val, str, len); - } else { - match = !strcmp(val, str); - } - - if (match) return 1; - } - - return 0; -} - - - -static int cb_check(Action *a, int status, char *resp, int invert) -{ - const char **value = a->data; - unsigned count = a->size; - unsigned n; - int yes; - - if (status) { - fprintf(stderr,"FAILED (%s)\n", resp); - return status; - } - - yes = match(resp, value, count); - if (invert) yes = !yes; - - if (yes) { - fprintf(stderr,"OKAY\n"); - return 0; - } - - fprintf(stderr,"FAILED\n\n"); - fprintf(stderr,"Device %s is '%s'.\n", a->cmd + 7, resp); - fprintf(stderr,"Update %s '%s'", - invert ? "rejects" : "requires", value[0]); - for (n = 1; n < count; n++) { - fprintf(stderr," or '%s'", value[n]); - } - fprintf(stderr,".\n\n"); - return -1; -} - -static int cb_require(Action *a, int status, char *resp) -{ - return cb_check(a, status, resp, 0); -} - -static int cb_reject(Action *a, int status, char *resp) -{ - return cb_check(a, status, resp, 1); -} - -void fb_queue_require(const char *var, int invert, unsigned nvalues, const char **value) -{ - Action *a; - a = queue_action(OP_QUERY, "getvar:%s", var); - a->data = value; - a->size = nvalues; - a->msg = mkmsg("checking %s", var); - a->func = invert ? cb_reject : cb_require; - if (a->data == 0) die("out of memory"); -} - -static int cb_display(Action *a, int status, char *resp) -{ - if (status) { - fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp); - return status; - } - fprintf(stderr, "%s: %s\n", (char*) a->data, resp); - return 0; -} - -void fb_queue_display(const char *var, const char *prettyname) -{ - Action *a; - a = queue_action(OP_QUERY, "getvar:%s", var); - a->data = strdup(prettyname); - if (a->data == 0) die("out of memory"); - a->func = cb_display; -} - -static int cb_do_nothing(Action *a, int status, char *resp) -{ - fprintf(stderr,"\n"); - return 0; -} - -void fb_queue_reboot(void) -{ - Action *a = queue_action(OP_COMMAND, "reboot"); - a->func = cb_do_nothing; - a->msg = "rebooting"; -} - -void fb_queue_command(const char *cmd, const char *msg) -{ - Action *a = queue_action(OP_COMMAND, cmd); - a->msg = msg; -} - -void fb_queue_download(const char *name, void *data, unsigned size) -{ - Action *a = queue_action(OP_DOWNLOAD, ""); - a->data = data; - a->size = size; - a->msg = mkmsg("downloading '%s'", name); -} - -void fb_queue_notice(const char *notice) -{ - Action *a = queue_action(OP_NOTICE, ""); - a->data = (void*) notice; -} - -void fb_execute_queue(usb_handle *usb) -{ - Action *a; - char resp[FB_RESPONSE_SZ+1]; - int status; - - a = action_list; - resp[FB_RESPONSE_SZ] = 0; - - for (a = action_list; a; a = a->next) { - if (a->msg) { - fprintf(stderr,"%s... ",a->msg); - } - if (a->op == OP_DOWNLOAD) { - status = fb_download_data(usb, a->data, a->size); - status = a->func(a, status, status ? fb_get_error() : ""); - if (status) break; - } else if (a->op == OP_COMMAND) { - status = fb_command(usb, a->cmd); - status = a->func(a, status, status ? fb_get_error() : ""); - if (status) break; - } else if (a->op == OP_QUERY) { - status = fb_command_response(usb, a->cmd, resp); - status = a->func(a, status, status ? fb_get_error() : resp); - if (status) break; - } else if (a->op == OP_NOTICE) { - fprintf(stderr,"%s\n",(char*)a->data); - } else { - die("bogus action"); - } - } -} - diff --git a/fastboot/engineering_key.p12 b/fastboot/engineering_key.p12 deleted file mode 100644 index d8183b055d375152f557fdfe3d593f4f444b51e8..0000000000000000000000000000000000000000 Binary files a/fastboot/engineering_key.p12 and /dev/null differ diff --git a/fastboot/fastboot.c b/fastboot/fastboot.c deleted file mode 100644 index e220dbeab189031f0ec5dadc6522da24eb78aa10..0000000000000000000000000000000000000000 --- a/fastboot/fastboot.c +++ /dev/null @@ -1,673 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <limits.h> -#include <ctype.h> - -#include <sys/time.h> -#include <bootimg.h> -#include <zipfile/zipfile.h> - -#include "fastboot.h" - -static usb_handle *usb = 0; -static const char *serial = 0; -static const char *product = 0; -static const char *cmdline = 0; -static int wipe_data = 0; -static unsigned short vendor_id = 0; - -void die(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr,"error: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr,"\n"); - va_end(ap); - exit(1); -} - -void get_my_path(char *path); - -char *find_item(const char *item, const char *product) -{ - char *dir; - char *fn; - char path[PATH_MAX + 128]; - - if(!strcmp(item,"boot")) { - fn = "boot.img"; - } else if(!strcmp(item,"recovery")) { - fn = "recovery.img"; - } else if(!strcmp(item,"system")) { - fn = "system.img"; - } else if(!strcmp(item,"userdata")) { - fn = "userdata.img"; - } else if(!strcmp(item,"info")) { - fn = "android-info.txt"; - } else { - fprintf(stderr,"unknown partition '%s'\n", item); - return 0; - } - - if(product) { - get_my_path(path); - sprintf(path + strlen(path), - "../../../target/product/%s/%s", product, fn); - return strdup(path); - } - - dir = getenv("ANDROID_PRODUCT_OUT"); - if((dir == 0) || (dir[0] == 0)) { - die("neither -p product specified nor ANDROID_PRODUCT_OUT set"); - return 0; - } - - sprintf(path, "%s/%s", dir, fn); - return strdup(path); -} - -#ifdef _WIN32 -void *load_file(const char *fn, unsigned *_sz); -#else -void *load_file(const char *fn, unsigned *_sz) -{ - char *data; - int sz; - int fd; - - data = 0; - fd = open(fn, O_RDONLY); - if(fd < 0) return 0; - - sz = lseek(fd, 0, SEEK_END); - if(sz < 0) goto oops; - - if(lseek(fd, 0, SEEK_SET) != 0) goto oops; - - data = (char*) malloc(sz); - if(data == 0) goto oops; - - if(read(fd, data, sz) != sz) goto oops; - close(fd); - - if(_sz) *_sz = sz; - return data; - -oops: - close(fd); - if(data != 0) free(data); - return 0; -} -#endif - -int match_fastboot(usb_ifc_info *info) -{ - if(!(vendor_id && (info->dev_vendor == vendor_id)) && - (info->dev_vendor != 0x18d1) && - (info->dev_vendor != 0x0bb4)) return -1; - if(info->ifc_class != 0xff) return -1; - if(info->ifc_subclass != 0x42) return -1; - if(info->ifc_protocol != 0x03) return -1; - // require matching serial number if a serial number is specified - // at the command line with the -s option. - if (serial && strcmp(serial, info->serial_number) != 0) return -1; - return 0; -} - -int list_devices_callback(usb_ifc_info *info) -{ - if (match_fastboot(info) == 0) { - char* serial = info->serial_number; - if (!serial[0]) { - serial = "????????????"; - } - // output compatible with "adb devices" - printf("%s\tfastboot\n", serial); - } - - return -1; -} - -usb_handle *open_device(void) -{ - static usb_handle *usb = 0; - int announce = 1; - - if(usb) return usb; - - for(;;) { - usb = usb_open(match_fastboot); - if(usb) return usb; - if(announce) { - announce = 0; - fprintf(stderr,"< waiting for device >\n"); - } - sleep(1); - } -} - -void list_devices(void) { - // We don't actually open a USB device here, - // just getting our callback called so we can - // list all the connected devices. - usb_open(list_devices_callback); -} - -void usage(void) -{ - fprintf(stderr, -/* 1234567890123456789012345678901234567890123456789012345678901234567890123456 */ - "usage: fastboot [ <option> ] <command>\n" - "\n" - "commands:\n" - " update <filename> reflash device from update.zip\n" - " flashall flash boot + recovery + system\n" - " flash <partition> [ <filename> ] write a file to a flash partition\n" - " erase <partition> erase a flash partition\n" - " getvar <variable> display a bootloader variable\n" - " boot <kernel> [ <ramdisk> ] download and boot kernel\n" - " flash:raw boot <kernel> [ <ramdisk> ] create bootimage and flash it\n" - " devices list all connected devices\n" - " reboot reboot device normally\n" - " reboot-bootloader reboot device into bootloader\n" - "\n" - "options:\n" - " -w erase userdata and cache\n" - " -s <serial number> specify device serial number\n" - " -p <product> specify product name\n" - " -c <cmdline> override kernel commandline\n" - " -i <vendor id> specify a custom USB vendor id\n" - ); - exit(1); -} - -void *load_bootable_image(const char *kernel, const char *ramdisk, - unsigned *sz, const char *cmdline) -{ - void *kdata = 0, *rdata = 0; - unsigned ksize = 0, rsize = 0; - void *bdata; - unsigned bsize; - - if(kernel == 0) { - fprintf(stderr, "no image specified\n"); - return 0; - } - - kdata = load_file(kernel, &ksize); - if(kdata == 0) { - fprintf(stderr, "cannot load '%s'\n", kernel); - return 0; - } - - /* is this actually a boot image? */ - if(!memcmp(kdata, BOOT_MAGIC, BOOT_MAGIC_SIZE)) { - if(cmdline) bootimg_set_cmdline((boot_img_hdr*) kdata, cmdline); - - if(ramdisk) { - fprintf(stderr, "cannot boot a boot.img *and* ramdisk\n"); - return 0; - } - - *sz = ksize; - return kdata; - } - - if(ramdisk) { - rdata = load_file(ramdisk, &rsize); - if(rdata == 0) { - fprintf(stderr,"cannot load '%s'\n", ramdisk); - return 0; - } - } - - fprintf(stderr,"creating boot image...\n"); - bdata = mkbootimg(kdata, ksize, rdata, rsize, 0, 0, 2048, &bsize); - if(bdata == 0) { - fprintf(stderr,"failed to create boot.img\n"); - return 0; - } - if(cmdline) bootimg_set_cmdline((boot_img_hdr*) bdata, cmdline); - fprintf(stderr,"creating boot image - %d bytes\n", bsize); - *sz = bsize; - - return bdata; -} - -void *unzip_file(zipfile_t zip, const char *name, unsigned *sz) -{ - void *data; - zipentry_t entry; - unsigned datasz; - - entry = lookup_zipentry(zip, name); - if (entry == NULL) { - fprintf(stderr, "archive does not contain '%s'\n", name); - return 0; - } - - *sz = get_zipentry_size(entry); - - datasz = *sz * 1.001; - data = malloc(datasz); - - if(data == 0) { - fprintf(stderr, "failed to allocate %d bytes\n", *sz); - return 0; - } - - if (decompress_zipentry(entry, data, datasz)) { - fprintf(stderr, "failed to unzip '%s' from archive\n", name); - free(data); - return 0; - } - - return data; -} - -static char *strip(char *s) -{ - int n; - while(*s && isspace(*s)) s++; - n = strlen(s); - while(n-- > 0) { - if(!isspace(s[n])) break; - s[n] = 0; - } - return s; -} - -#define MAX_OPTIONS 32 -static int setup_requirement_line(char *name) -{ - char *val[MAX_OPTIONS]; - const char **out; - unsigned n, count; - char *x; - int invert = 0; - - if (!strncmp(name, "reject ", 7)) { - name += 7; - invert = 1; - } else if (!strncmp(name, "require ", 8)) { - name += 8; - invert = 0; - } - - x = strchr(name, '='); - if (x == 0) return 0; - *x = 0; - val[0] = x + 1; - - for(count = 1; count < MAX_OPTIONS; count++) { - x = strchr(val[count - 1],'|'); - if (x == 0) break; - *x = 0; - val[count] = x + 1; - } - - name = strip(name); - for(n = 0; n < count; n++) val[n] = strip(val[n]); - - name = strip(name); - if (name == 0) return -1; - - /* work around an unfortunate name mismatch */ - if (!strcmp(name,"board")) name = "product"; - - out = malloc(sizeof(char*) * count); - if (out == 0) return -1; - - for(n = 0; n < count; n++) { - out[n] = strdup(strip(val[n])); - if (out[n] == 0) return -1; - } - - fb_queue_require(name, invert, n, out); - return 0; -} - -static void setup_requirements(char *data, unsigned sz) -{ - char *s; - - s = data; - while (sz-- > 0) { - if(*s == '\n') { - *s++ = 0; - if (setup_requirement_line(data)) { - die("out of memory"); - } - data = s; - } else { - s++; - } - } -} - -void queue_info_dump(void) -{ - fb_queue_notice("--------------------------------------------"); - fb_queue_display("version-bootloader", "Bootloader Version..."); - fb_queue_display("version-baseband", "Baseband Version....."); - fb_queue_display("serialno", "Serial Number........"); - fb_queue_notice("--------------------------------------------"); -} - -void do_update_signature(zipfile_t zip, char *fn) -{ - void *data; - unsigned sz; - data = unzip_file(zip, fn, &sz); - if (data == 0) return; - fb_queue_download("signature", data, sz); - fb_queue_command("signature", "installing signature"); -} - -void do_update(char *fn) -{ - void *zdata; - unsigned zsize; - void *data; - unsigned sz; - zipfile_t zip; - - queue_info_dump(); - - zdata = load_file(fn, &zsize); - if (zdata == 0) die("failed to load '%s'", fn); - - zip = init_zipfile(zdata, zsize); - if(zip == 0) die("failed to access zipdata in '%s'"); - - data = unzip_file(zip, "android-info.txt", &sz); - if (data == 0) { - char *tmp; - /* fallback for older zipfiles */ - data = unzip_file(zip, "android-product.txt", &sz); - if ((data == 0) || (sz < 1)) { - die("update package has no android-info.txt or android-product.txt"); - } - tmp = malloc(sz + 128); - if (tmp == 0) die("out of memory"); - sprintf(tmp,"board=%sversion-baseband=0.66.04.19\n",(char*)data); - data = tmp; - sz = strlen(tmp); - } - - setup_requirements(data, sz); - - data = unzip_file(zip, "boot.img", &sz); - if (data == 0) die("update package missing boot.img"); - do_update_signature(zip, "boot.sig"); - fb_queue_flash("boot", data, sz); - - data = unzip_file(zip, "recovery.img", &sz); - if (data != 0) { - do_update_signature(zip, "recovery.sig"); - fb_queue_flash("recovery", data, sz); - } - - data = unzip_file(zip, "system.img", &sz); - if (data == 0) die("update package missing system.img"); - do_update_signature(zip, "system.sig"); - fb_queue_flash("system", data, sz); -} - -void do_send_signature(char *fn) -{ - void *data; - unsigned sz; - char *xtn; - - xtn = strrchr(fn, '.'); - if (!xtn) return; - if (strcmp(xtn, ".img")) return; - - strcpy(xtn,".sig"); - data = load_file(fn, &sz); - strcpy(xtn,".img"); - if (data == 0) return; - fb_queue_download("signature", data, sz); - fb_queue_command("signature", "installing signature"); -} - -void do_flashall(void) -{ - char *fname; - void *data; - unsigned sz; - - queue_info_dump(); - - fname = find_item("info", product); - if (fname == 0) die("cannot find android-info.txt"); - data = load_file(fname, &sz); - if (data == 0) die("could not load android-info.txt"); - setup_requirements(data, sz); - - fname = find_item("boot", product); - data = load_file(fname, &sz); - if (data == 0) die("could not load boot.img"); - do_send_signature(fname); - fb_queue_flash("boot", data, sz); - - fname = find_item("recovery", product); - data = load_file(fname, &sz); - if (data != 0) { - do_send_signature(fname); - fb_queue_flash("recovery", data, sz); - } - - fname = find_item("system", product); - data = load_file(fname, &sz); - if (data == 0) die("could not load system.img"); - do_send_signature(fname); - fb_queue_flash("system", data, sz); -} - -#define skip(n) do { argc -= (n); argv += (n); } while (0) -#define require(n) do { if (argc < (n)) usage(); } while (0) - -int do_oem_command(int argc, char **argv) -{ - int i; - char command[256]; - if (argc <= 1) return 0; - - command[0] = 0; - while(1) { - strcat(command,*argv); - skip(1); - if(argc == 0) break; - strcat(command," "); - } - - fb_queue_command(command,""); - return 0; -} - -int main(int argc, char **argv) -{ - int wants_wipe = 0; - int wants_reboot = 0; - int wants_reboot_bootloader = 0; - void *data; - unsigned sz; - - skip(1); - if (argc == 0) { - usage(); - return 0; - } - - if (!strcmp(*argv, "devices")) { - list_devices(); - return 0; - } - - while (argc > 0) { - if(!strcmp(*argv, "-w")) { - wants_wipe = 1; - skip(1); - } else if(!strcmp(*argv, "-s")) { - require(2); - serial = argv[1]; - skip(2); - } else if(!strcmp(*argv, "-p")) { - require(2); - product = argv[1]; - skip(2); - } else if(!strcmp(*argv, "-c")) { - require(2); - cmdline = argv[1]; - skip(2); - } else if(!strcmp(*argv, "-i")) { - char *endptr = NULL; - unsigned long val; - - require(2); - val = strtoul(argv[1], &endptr, 0); - if (!endptr || *endptr != '\0' || (val & ~0xffff)) - die("invalid vendor id '%s'", argv[1]); - vendor_id = (unsigned short)val; - skip(2); - } else if(!strcmp(*argv, "getvar")) { - require(2); - fb_queue_display(argv[1], argv[1]); - skip(2); - } else if(!strcmp(*argv, "erase")) { - require(2); - fb_queue_erase(argv[1]); - skip(2); - } else if(!strcmp(*argv, "signature")) { - require(2); - data = load_file(argv[1], &sz); - if (data == 0) die("could not load '%s'", argv[1]); - if (sz != 256) die("signature must be 256 bytes"); - fb_queue_download("signature", data, sz); - fb_queue_command("signature", "installing signature"); - skip(2); - } else if(!strcmp(*argv, "reboot")) { - wants_reboot = 1; - skip(1); - } else if(!strcmp(*argv, "reboot-bootloader")) { - wants_reboot_bootloader = 1; - skip(1); - } else if (!strcmp(*argv, "continue")) { - fb_queue_command("continue", "resuming boot"); - skip(1); - } else if(!strcmp(*argv, "boot")) { - char *kname = 0; - char *rname = 0; - skip(1); - if (argc > 0) { - kname = argv[0]; - skip(1); - } - if (argc > 0) { - rname = argv[0]; - skip(1); - } - data = load_bootable_image(kname, rname, &sz, cmdline); - if (data == 0) return 1; - fb_queue_download("boot.img", data, sz); - fb_queue_command("boot", "booting"); - } else if(!strcmp(*argv, "flash")) { - char *pname = argv[1]; - char *fname = 0; - require(2); - if (argc > 2) { - fname = argv[2]; - skip(3); - } else { - fname = find_item(pname, product); - skip(2); - } - if (fname == 0) die("cannot determine image filename for '%s'", pname); - data = load_file(fname, &sz); - if (data == 0) die("cannot load '%s'\n", fname); - fb_queue_flash(pname, data, sz); - } else if(!strcmp(*argv, "flash:raw")) { - char *pname = argv[1]; - char *kname = argv[2]; - char *rname = 0; - require(3); - if(argc > 3) { - rname = argv[3]; - skip(4); - } else { - skip(3); - } - data = load_bootable_image(kname, rname, &sz, cmdline); - if (data == 0) die("cannot load bootable image"); - fb_queue_flash(pname, data, sz); - } else if(!strcmp(*argv, "flashall")) { - skip(1); - do_flashall(); - wants_reboot = 1; - } else if(!strcmp(*argv, "update")) { - if (argc > 1) { - do_update(argv[1]); - skip(2); - } else { - do_update("update.zip"); - skip(1); - } - wants_reboot = 1; - } else if(!strcmp(*argv, "oem")) { - argc = do_oem_command(argc, argv); - } else { - usage(); - } - } - - if (wants_wipe) { - fb_queue_erase("userdata"); - fb_queue_erase("cache"); - } - if (wants_reboot) { - fb_queue_reboot(); - } else if (wants_reboot_bootloader) { - fb_queue_command("reboot-bootloader", "rebooting into bootloader"); - } - - usb = open_device(); - - fb_execute_queue(usb); - return 0; -} diff --git a/fastboot/fastboot.h b/fastboot/fastboot.h deleted file mode 100644 index a36c569e159b7fc7062322e99ccd3b2b29ee5dcb..0000000000000000000000000000000000000000 --- a/fastboot/fastboot.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#ifndef _FASTBOOT_H_ -#define _FASTBOOT_H_ - -#include "usb.h" - -/* protocol.c - fastboot protocol */ -int fb_command(usb_handle *usb, const char *cmd); -int fb_command_response(usb_handle *usb, const char *cmd, char *response); -int fb_download_data(usb_handle *usb, const void *data, unsigned size); -char *fb_get_error(void); - -#define FB_COMMAND_SZ 64 -#define FB_RESPONSE_SZ 64 - -/* engine.c - high level command queue engine */ -void fb_queue_flash(const char *ptn, void *data, unsigned sz);; -void fb_queue_erase(const char *ptn); -void fb_queue_require(const char *var, int invert, unsigned nvalues, const char **value); -void fb_queue_display(const char *var, const char *prettyname); -void fb_queue_reboot(void); -void fb_queue_command(const char *cmd, const char *msg); -void fb_queue_download(const char *name, void *data, unsigned size); -void fb_queue_notice(const char *notice); -void fb_execute_queue(usb_handle *usb); - -/* util stuff */ -void die(const char *fmt, ...); - -#endif diff --git a/fastboot/genkey.sh b/fastboot/genkey.sh deleted file mode 100755 index 011e902ef80cd3e4375e532b8c148648b5728f2f..0000000000000000000000000000000000000000 --- a/fastboot/genkey.sh +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/bash - -if [ $# -ne 2 ] -then - echo "Usage: $0 alias \"pass phrase\"" - exit -1 -fi - -# Generate a 2048 bit RSA key with public exponent 3. -# Encrypt private key with provided password. -openssl genrsa -3 -out $1.pem -passout pass:"$2" 2048 - -# Create a self-signed cert for this key. -openssl req -new -x509 -key $1.pem -passin pass:"$2" \ - -out $1-cert.pem \ - -batch -days 10000 - -# Create a PKCS12 store containing the generated private key. -# Protect the keystore and the private key with the provided password. -openssl pkcs12 -export -in $1-cert.pem -inkey $1.pem -passin pass:"$2" \ - -out $1.p12 -name $1 -passout pass:"$2" - -rm $1.pem -rm $1-cert.pem - diff --git a/fastboot/p12topem.sh b/fastboot/p12topem.sh deleted file mode 100755 index f081eb5312a49a3b8c8e1058a4dc9f5adf2fa797..0000000000000000000000000000000000000000 --- a/fastboot/p12topem.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -if [ $# -ne 2 ] -then - echo "Usage: $0 alias passphrase" - exit -1 -fi - -openssl pkcs12 -passin pass:"$2" -passout pass:"$2" -in $1.p12 -out $1.pem diff --git a/fastboot/protocol.c b/fastboot/protocol.c deleted file mode 100644 index c788a12ff0ef1a1f5ef161c6fe17b592fdcf0574..0000000000000000000000000000000000000000 --- a/fastboot/protocol.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include "fastboot.h" - -static char ERROR[128]; - -char *fb_get_error(void) -{ - return ERROR; -} - -static int check_response(usb_handle *usb, unsigned size, - unsigned data_okay, char *response) -{ - unsigned char status[65]; - int r; - - for(;;) { - r = usb_read(usb, status, 64); - if(r < 0) { - sprintf(ERROR, "status read failed (%s)", strerror(errno)); - usb_close(usb); - return -1; - } - status[r] = 0; - - if(r < 4) { - sprintf(ERROR, "status malformed (%d bytes)", r); - usb_close(usb); - return -1; - } - - if(!memcmp(status, "INFO", 4)) { - fprintf(stderr,"%s\n", status); - continue; - } - - if(!memcmp(status, "OKAY", 4)) { - if(response) { - strcpy(response, (char*) status + 4); - } - return 0; - } - - if(!memcmp(status, "FAIL", 4)) { - if(r > 4) { - sprintf(ERROR, "remote: %s", status + 4); - } else { - strcpy(ERROR, "remote failure"); - } - return -1; - } - - if(!memcmp(status, "DATA", 4) && data_okay){ - unsigned dsize = strtoul((char*) status + 4, 0, 16); - if(dsize > size) { - strcpy(ERROR, "data size too large"); - usb_close(usb); - return -1; - } - return dsize; - } - - strcpy(ERROR,"unknown status code"); - usb_close(usb); - break; - } - - return -1; -} - -static int _command_send(usb_handle *usb, const char *cmd, - const void *data, unsigned size, - char *response) -{ - int cmdsize = strlen(cmd); - int r; - - if(response) { - response[0] = 0; - } - - if(cmdsize > 64) { - sprintf(ERROR,"command too large"); - return -1; - } - - if(usb_write(usb, cmd, cmdsize) != cmdsize) { - sprintf(ERROR,"command write failed (%s)", strerror(errno)); - usb_close(usb); - return -1; - } - - if(data == 0) { - return check_response(usb, size, 0, response); - } - - r = check_response(usb, size, 1, 0); - if(r < 0) { - return -1; - } - size = r; - - if(size) { - r = usb_write(usb, data, size); - if(r < 0) { - sprintf(ERROR, "data transfer failure (%s)", strerror(errno)); - usb_close(usb); - return -1; - } - if(r != ((int) size)) { - sprintf(ERROR, "data transfer failure (short transfer)"); - usb_close(usb); - return -1; - } - } - - r = check_response(usb, 0, 0, 0); - if(r < 0) { - return -1; - } else { - return size; - } -} - -int fb_command(usb_handle *usb, const char *cmd) -{ - return _command_send(usb, cmd, 0, 0, 0); -} - -int fb_command_response(usb_handle *usb, const char *cmd, char *response) -{ - return _command_send(usb, cmd, 0, 0, response); -} - -int fb_download_data(usb_handle *usb, const void *data, unsigned size) -{ - char cmd[64]; - int r; - - sprintf(cmd, "download:%08x", size); - r = _command_send(usb, cmd, data, size, 0); - - if(r < 0) { - return -1; - } else { - return 0; - } -} - diff --git a/fastboot/signfile.sh b/fastboot/signfile.sh deleted file mode 100755 index 3188d2d9603e66da209825a0ae35a57bd0df5f4d..0000000000000000000000000000000000000000 --- a/fastboot/signfile.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -if [ $# -ne 3 ] -then - echo "Usage: $0 alias filename passpharse" - exit -1 -fi - -openssl dgst -passin pass:"$3" -binary -sha1 -sign $1.pem $2 > $2.sign - diff --git a/fastboot/usb.h b/fastboot/usb.h deleted file mode 100644 index f3ec5bfdad4ded57ca7169be833ce6f8b1a7a5f4..0000000000000000000000000000000000000000 --- a/fastboot/usb.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#ifndef _USB_H_ -#define _USB_H_ - -typedef struct usb_handle usb_handle; - -typedef struct usb_ifc_info usb_ifc_info; - -struct usb_ifc_info -{ - /* from device descriptor */ - unsigned short dev_vendor; - unsigned short dev_product; - - unsigned char dev_class; - unsigned char dev_subclass; - unsigned char dev_protocol; - - unsigned char ifc_class; - unsigned char ifc_subclass; - unsigned char ifc_protocol; - - unsigned char has_bulk_in; - unsigned char has_bulk_out; - - char serial_number[256]; -}; - -typedef int (*ifc_match_func)(usb_ifc_info *ifc); - -usb_handle *usb_open(ifc_match_func callback); -int usb_close(usb_handle *h); -int usb_read(usb_handle *h, void *_data, int len); -int usb_write(usb_handle *h, const void *_data, int len); - - -#endif diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.c deleted file mode 100644 index 06c62b84c7a1cf6af6a16adccebd3dd9d6875e76..0000000000000000000000000000000000000000 --- a/fastboot/usb_linux.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> - -#include <sys/ioctl.h> -#include <sys/types.h> -#include <dirent.h> -#include <fcntl.h> -#include <errno.h> -#include <pthread.h> -#include <ctype.h> - -#include <linux/usbdevice_fs.h> -#include <linux/usbdevice_fs.h> -#include <linux/version.h> -#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 20) -#include <linux/usb/ch9.h> -#else -#include <linux/usb_ch9.h> -#endif -#include <asm/byteorder.h> - -#include "usb.h" - -#if TRACE_USB -#define DBG1(x...) fprintf(stderr, x) -#define DBG(x...) fprintf(stderr, x) -#else -#define DBG(x...) -#define DBG1(x...) -#endif - -struct usb_handle -{ - char fname[64]; - int desc; - unsigned char ep_in; - unsigned char ep_out; -}; - -static inline int badname(const char *name) -{ - while(*name) { - if(!isdigit(*name++)) return 1; - } - return 0; -} - -static int check(void *_desc, int len, unsigned type, int size) -{ - unsigned char *desc = _desc; - - if(len < size) return -1; - if(desc[0] < size) return -1; - if(desc[0] > len) return -1; - if(desc[1] != type) return -1; - - return 0; -} - -static int filter_usb_device(int fd, char *ptr, int len, ifc_match_func callback, - int *ept_in_id, int *ept_out_id, int *ifc_id) -{ - struct usb_device_descriptor *dev; - struct usb_config_descriptor *cfg; - struct usb_interface_descriptor *ifc; - struct usb_endpoint_descriptor *ept; - struct usb_ifc_info info; - - int in, out; - unsigned i; - unsigned e; - - if(check(ptr, len, USB_DT_DEVICE, USB_DT_DEVICE_SIZE)) - return -1; - dev = (void*) ptr; - len -= dev->bLength; - ptr += dev->bLength; - - if(check(ptr, len, USB_DT_CONFIG, USB_DT_CONFIG_SIZE)) - return -1; - cfg = (void*) ptr; - len -= cfg->bLength; - ptr += cfg->bLength; - - info.dev_vendor = dev->idVendor; - info.dev_product = dev->idProduct; - info.dev_class = dev->bDeviceClass; - info.dev_subclass = dev->bDeviceSubClass; - info.dev_protocol = dev->bDeviceProtocol; - - // read device serial number (if there is one) - info.serial_number[0] = 0; - if (dev->iSerialNumber) { - struct usbdevfs_ctrltransfer ctrl; - __u16 buffer[128]; - int result; - - memset(buffer, 0, sizeof(buffer)); - - ctrl.bRequestType = USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE; - ctrl.bRequest = USB_REQ_GET_DESCRIPTOR; - ctrl.wValue = (USB_DT_STRING << 8) | dev->iSerialNumber; - ctrl.wIndex = 0; - ctrl.wLength = sizeof(buffer); - ctrl.data = buffer; - - result = ioctl(fd, USBDEVFS_CONTROL, &ctrl); - if (result > 0) { - int i; - // skip first word, and copy the rest to the serial string, changing shorts to bytes. - result /= 2; - for (i = 1; i < result; i++) - info.serial_number[i - 1] = buffer[i]; - info.serial_number[i - 1] = 0; - } - } - - for(i = 0; i < cfg->bNumInterfaces; i++) { - if(check(ptr, len, USB_DT_INTERFACE, USB_DT_INTERFACE_SIZE)) - return -1; - ifc = (void*) ptr; - len -= ifc->bLength; - ptr += ifc->bLength; - - in = -1; - out = -1; - info.ifc_class = ifc->bInterfaceClass; - info.ifc_subclass = ifc->bInterfaceSubClass; - info.ifc_protocol = ifc->bInterfaceProtocol; - - for(e = 0; e < ifc->bNumEndpoints; e++) { - if(check(ptr, len, USB_DT_ENDPOINT, USB_DT_ENDPOINT_SIZE)) - return -1; - ept = (void*) ptr; - len -= ept->bLength; - ptr += ept->bLength; - - if((ept->bmAttributes & 0x03) != 0x02) - continue; - - if(ept->bEndpointAddress & 0x80) { - in = ept->bEndpointAddress; - } else { - out = ept->bEndpointAddress; - } - } - - info.has_bulk_in = (in != -1); - info.has_bulk_out = (out != -1); - - if(callback(&info) == 0) { - *ept_in_id = in; - *ept_out_id = out; - *ifc_id = ifc->bInterfaceNumber; - return 0; - } - } - - return -1; -} - -static usb_handle *find_usb_device(const char *base, ifc_match_func callback) -{ - usb_handle *usb = 0; - char busname[64], devname[64]; - char desc[1024]; - int n, in, out, ifc; - - DIR *busdir, *devdir; - struct dirent *de; - int fd; - - busdir = opendir(base); - if(busdir == 0) return 0; - - while((de = readdir(busdir)) && (usb == 0)) { - if(badname(de->d_name)) continue; - - sprintf(busname, "%s/%s", base, de->d_name); - devdir = opendir(busname); - if(devdir == 0) continue; - -// DBG("[ scanning %s ]\n", busname); - while((de = readdir(devdir)) && (usb == 0)) { - - if(badname(de->d_name)) continue; - sprintf(devname, "%s/%s", busname, de->d_name); - -// DBG("[ scanning %s ]\n", devname); - if((fd = open(devname, O_RDWR)) < 0) { - continue; - } - - n = read(fd, desc, sizeof(desc)); - - if(filter_usb_device(fd, desc, n, callback, &in, &out, &ifc) == 0){ - usb = calloc(1, sizeof(usb_handle)); - strcpy(usb->fname, devname); - usb->ep_in = in; - usb->ep_out = out; - usb->desc = fd; - - n = ioctl(fd, USBDEVFS_CLAIMINTERFACE, &ifc); - if(n != 0) { - close(fd); - free(usb); - usb = 0; - continue; - } - } else { - close(fd); - } - } - closedir(devdir); - } - closedir(busdir); - - return usb; -} - -int usb_write(usb_handle *h, const void *_data, int len) -{ - unsigned char *data = (unsigned char*) _data; - unsigned count = 0; - struct usbdevfs_bulktransfer bulk; - int n; - - if(h->ep_out == 0) { - return -1; - } - - if(len == 0) { - bulk.ep = h->ep_out; - bulk.len = 0; - bulk.data = data; - bulk.timeout = 0; - - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - if(n != 0) { - fprintf(stderr,"ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - return 0; - } - - while(len > 0) { - int xfer; - xfer = (len > 4096) ? 4096 : len; - - bulk.ep = h->ep_out; - bulk.len = xfer; - bulk.data = data; - bulk.timeout = 0; - - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - if(n != xfer) { - DBG("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - - count += xfer; - len -= xfer; - data += xfer; - } - - return count; -} - -int usb_read(usb_handle *h, void *_data, int len) -{ - unsigned char *data = (unsigned char*) _data; - unsigned count = 0; - struct usbdevfs_bulktransfer bulk; - int n; - - if(h->ep_in == 0) { - return -1; - } - - while(len > 0) { - int xfer = (len > 4096) ? 4096 : len; - - bulk.ep = h->ep_in; - bulk.len = xfer; - bulk.data = data; - bulk.timeout = 0; - - DBG("[ usb read %d fd = %d], fname=%s\n", xfer, h->desc, h->fname); - n = ioctl(h->desc, USBDEVFS_BULK, &bulk); - DBG("[ usb read %d ] = %d, fname=%s\n", xfer, n, h->fname); - - if(n < 0) { - DBG1("ERROR: n = %d, errno = %d (%s)\n", - n, errno, strerror(errno)); - return -1; - } - - count += n; - len -= n; - data += n; - - if(n < xfer) { - break; - } - } - - return count; -} - -void usb_kick(usb_handle *h) -{ - int fd; - - fd = h->desc; - h->desc = -1; - if(fd >= 0) { - close(fd); - DBG("[ usb closed %d ]\n", fd); - } -} - -int usb_close(usb_handle *h) -{ - int fd; - - fd = h->desc; - h->desc = -1; - if(fd >= 0) { - close(fd); - DBG("[ usb closed %d ]\n", fd); - } - - return 0; -} - -usb_handle *usb_open(ifc_match_func callback) -{ - return find_usb_device("/dev/bus/usb", callback); -} - - diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.c deleted file mode 100644 index d6a826094b83da4398c4d320d856f00742368c37..0000000000000000000000000000000000000000 --- a/fastboot/usb_osx.c +++ /dev/null @@ -1,538 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <CoreFoundation/CoreFoundation.h> -#include <IOKit/IOKitLib.h> -#include <IOKit/IOCFPlugIn.h> -#include <IOKit/usb/IOUSBLib.h> -#include <IOKit/IOMessage.h> -#include <mach/mach_port.h> - -#include "usb.h" - - -/* - * Internal helper functions and associated definitions. - */ - -#if TRACE_USB -#define WARN(x...) fprintf(stderr, x) -#else -#define WARN(x...) -#endif - -#define ERR(x...) fprintf(stderr, "ERROR: " x) - -/** An open usb device */ -struct usb_handle -{ - int success; - ifc_match_func callback; - usb_ifc_info info; - - UInt8 bulkIn; - UInt8 bulkOut; - IOUSBInterfaceInterface190 **interface; - unsigned int zero_mask; -}; - -/** Try out all the interfaces and see if there's a match. Returns 0 on - * success, -1 on failure. */ -static int try_interfaces(IOUSBDeviceInterface **dev, usb_handle *handle) { - IOReturn kr; - IOUSBFindInterfaceRequest request; - io_iterator_t iterator; - io_service_t usbInterface; - IOCFPlugInInterface **plugInInterface; - IOUSBInterfaceInterface190 **interface = NULL; - HRESULT result; - SInt32 score; - UInt8 interfaceNumEndpoints; - UInt8 endpoint; - UInt8 configuration; - - // Placing the constant KIOUSBFindInterfaceDontCare into the following - // fields of the IOUSBFindInterfaceRequest structure will allow us to - // find all of the interfaces - request.bInterfaceClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare; - request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare; - request.bAlternateSetting = kIOUSBFindInterfaceDontCare; - - // SetConfiguration will kill an existing UMS connection, so let's - // not do this if not necessary. - configuration = 0; - (*dev)->GetConfiguration(dev, &configuration); - if (configuration != 1) - (*dev)->SetConfiguration(dev, 1); - - // Get an iterator for the interfaces on the device - kr = (*dev)->CreateInterfaceIterator(dev, &request, &iterator); - - if (kr != 0) { - ERR("Couldn't create a device interface iterator: (%08x)\n", kr); - return -1; - } - - while ((usbInterface = IOIteratorNext(iterator))) { - // Create an intermediate plugin - kr = IOCreatePlugInInterfaceForService( - usbInterface, - kIOUSBInterfaceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugInInterface, - &score); - - // No longer need the usbInterface object now that we have the plugin - (void) IOObjectRelease(usbInterface); - - if ((kr != 0) || (!plugInInterface)) { - WARN("Unable to create plugin (%08x)\n", kr); - continue; - } - - // Now create the interface interface for the interface - result = (*plugInInterface)->QueryInterface( - plugInInterface, - CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID), - (LPVOID) &interface); - - // No longer need the intermediate plugin - (*plugInInterface)->Release(plugInInterface); - - if (result || !interface) { - ERR("Couldn't create interface interface: (%08x)\n", - (unsigned int) result); - // continue so we can try the next interface - continue; - } - - /* - * Now open the interface. This will cause the pipes - * associated with the endpoints in the interface descriptor - * to be instantiated. - */ - - /* - * TODO: Earlier comments here indicated that it was a bad - * idea to just open any interface, because opening "mass - * storage endpoints" is bad. However, the only way to find - * out if an interface does bulk in or out is to open it, and - * the framework in this application wants to be told about - * bulk in / out before deciding whether it actually wants to - * use the interface. Maybe something needs to be done about - * this situation. - */ - - kr = (*interface)->USBInterfaceOpen(interface); - - if (kr != 0) { - WARN("Could not open interface: (%08x)\n", kr); - (void) (*interface)->Release(interface); - // continue so we can try the next interface - continue; - } - - // Get the number of endpoints associated with this interface. - kr = (*interface)->GetNumEndpoints(interface, &interfaceNumEndpoints); - - if (kr != 0) { - ERR("Unable to get number of endpoints: (%08x)\n", kr); - goto next_interface; - } - - // Get interface class, subclass and protocol - if ((*interface)->GetInterfaceClass(interface, &handle->info.ifc_class) != 0 || - (*interface)->GetInterfaceSubClass(interface, &handle->info.ifc_subclass) != 0 || - (*interface)->GetInterfaceProtocol(interface, &handle->info.ifc_protocol) != 0) - { - ERR("Unable to get interface class, subclass and protocol\n"); - goto next_interface; - } - - handle->info.has_bulk_in = 0; - handle->info.has_bulk_out = 0; - - // Iterate over the endpoints for this interface and see if there - // are any that do bulk in/out. - for (endpoint = 0; endpoint <= interfaceNumEndpoints; endpoint++) { - UInt8 transferType; - UInt16 maxPacketSize; - UInt8 interval; - UInt8 number; - UInt8 direction; - - kr = (*interface)->GetPipeProperties(interface, endpoint, - &direction, - &number, &transferType, &maxPacketSize, &interval); - - if (kr == 0) { - if (transferType != kUSBBulk) { - continue; - } - - if (direction == kUSBIn) { - handle->info.has_bulk_in = 1; - handle->bulkIn = endpoint; - } else if (direction == kUSBOut) { - handle->info.has_bulk_out = 1; - handle->bulkOut = endpoint; - } - - if (handle->info.ifc_protocol == 0x01) { - handle->zero_mask = maxPacketSize - 1; - } - } else { - ERR("could not get pipe properties\n"); - } - - if (handle->info.has_bulk_in && handle->info.has_bulk_out) { - break; - } - } - - if (handle->callback(&handle->info) == 0) { - handle->interface = interface; - handle->success = 1; - - /* - * Clear both the endpoints, because it has been observed - * that the Mac may otherwise (incorrectly) start out with - * them in bad state. - */ - - if (handle->info.has_bulk_in) { - kr = (*interface)->ClearPipeStallBothEnds(interface, - handle->bulkIn); - if (kr != 0) { - ERR("could not clear input pipe; result %d", kr); - return -1; - } - } - - if (handle->info.has_bulk_out) { - kr = (*interface)->ClearPipeStallBothEnds(interface, - handle->bulkOut); - if (kr != 0) { - ERR("could not clear output pipe; result %d", kr); - return -1; - } - } - - return 0; - } - -next_interface: - (*interface)->USBInterfaceClose(interface); - (*interface)->Release(interface); - } - - return 0; -} - -/** Try out the given device and see if there's a match. Returns 0 on - * success, -1 on failure. - */ -static int try_device(io_service_t device, usb_handle *handle) { - kern_return_t kr; - IOCFPlugInInterface **plugin = NULL; - IOUSBDeviceInterface182 **dev = NULL; - SInt32 score; - HRESULT result; - UInt8 serialIndex; - - // Create an intermediate plugin. - kr = IOCreatePlugInInterfaceForService(device, - kIOUSBDeviceUserClientTypeID, - kIOCFPlugInInterfaceID, - &plugin, &score); - - if ((kr != 0) || (plugin == NULL)) { - ERR("Unable to create a plug-in (%08x)\n", kr); - goto error; - } - - // Now create the device interface. - result = (*plugin)->QueryInterface(plugin, - CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev); - if ((result != 0) || (dev == NULL)) { - ERR("Couldn't create a device interface (%08x)\n", (int) result); - goto error; - } - - /* - * We don't need the intermediate interface after the device interface - * is created. - */ - IODestroyPlugInInterface(plugin); - - // So, we have a device, finally. Grab its vitals. - - kr = (*dev)->GetDeviceVendor(dev, &handle->info.dev_vendor); - if (kr != 0) { - ERR("GetDeviceVendor"); - goto error; - } - - kr = (*dev)->GetDeviceProduct(dev, &handle->info.dev_product); - if (kr != 0) { - ERR("GetDeviceProduct"); - goto error; - } - - kr = (*dev)->GetDeviceClass(dev, &handle->info.dev_class); - if (kr != 0) { - ERR("GetDeviceClass"); - goto error; - } - - kr = (*dev)->GetDeviceSubClass(dev, &handle->info.dev_subclass); - if (kr != 0) { - ERR("GetDeviceSubClass"); - goto error; - } - - kr = (*dev)->GetDeviceProtocol(dev, &handle->info.dev_protocol); - if (kr != 0) { - ERR("GetDeviceProtocol"); - goto error; - } - - kr = (*dev)->USBGetSerialNumberStringIndex(dev, &serialIndex); - - if (serialIndex > 0) { - IOUSBDevRequest req; - UInt16 buffer[256]; - - req.bmRequestType = USBmakebmRequestType(kUSBIn, kUSBStandard, kUSBDevice); - req.bRequest = kUSBRqGetDescriptor; - req.wValue = (kUSBStringDesc << 8) | serialIndex; - req.wIndex = 0; - req.pData = buffer; - req.wLength = sizeof(buffer); - kr = (*dev)->DeviceRequest(dev, &req); - - if (kr == kIOReturnSuccess && req.wLenDone > 0) { - int i, count; - - // skip first word, and copy the rest to the serial string, changing shorts to bytes. - count = (req.wLenDone - 1) / 2; - for (i = 0; i < count; i++) - handle->info.serial_number[i] = buffer[i + 1]; - handle->info.serial_number[i] = 0; - } - } else { - // device has no serial number - handle->info.serial_number[0] = 0; - } - - if (try_interfaces(dev, handle)) { - goto error; - } - - (*dev)->Release(dev); - return 0; - - error: - - if (dev != NULL) { - (*dev)->Release(dev); - } - - return -1; -} - - -/** Initializes the USB system. Returns 0 on success, -1 on error. */ -static int init_usb(ifc_match_func callback, usb_handle **handle) { - int ret = -1; - CFMutableDictionaryRef matchingDict; - kern_return_t result; - io_iterator_t iterator; - usb_handle h; - - h.success = 0; - h.callback = callback; - - /* - * Create our matching dictionary to find appropriate devices. - * IOServiceAddMatchingNotification consumes the reference, so we - * do not need to release it. - */ - matchingDict = IOServiceMatching(kIOUSBDeviceClassName); - - if (matchingDict == NULL) { - ERR("Couldn't create USB matching dictionary.\n"); - return -1; - } - - result = IOServiceGetMatchingServices( - kIOMasterPortDefault, matchingDict, &iterator); - - if (result != 0) { - ERR("Could not create iterator."); - return -1; - } - - for (;;) { - if (! IOIteratorIsValid(iterator)) { - /* - * Apple documentation advises resetting the iterator if - * it should become invalid during iteration. - */ - IOIteratorReset(iterator); - continue; - } - - io_service_t device = IOIteratorNext(iterator); - - if (device == 0) { - break; - } - - usb_ifc_info info; - - if (try_device(device, &h) != 0) { - IOObjectRelease(device); - ret = -1; - break; - } - - if (h.success) { - *handle = calloc(1, sizeof(usb_handle)); - memcpy(*handle, &h, sizeof(usb_handle)); - ret = 0; - break; - } - - IOObjectRelease(device); - } - - IOObjectRelease(iterator); - - return ret; -} - - - -/* - * Definitions of this file's public functions. - */ - -usb_handle *usb_open(ifc_match_func callback) { - usb_handle *handle = NULL; - - if (init_usb(callback, &handle) < 0) { - /* Something went wrong initializing USB. */ - return NULL; - } - - return handle; -} - -int usb_close(usb_handle *h) { - /* TODO: Something better here? */ - return 0; -} - -int usb_read(usb_handle *h, void *data, int len) { - IOReturn result; - UInt32 numBytes = len; - - if (len == 0) { - return 0; - } - - if (h == NULL) { - return -1; - } - - if (h->interface == NULL) { - ERR("usb_read interface was null\n"); - return -1; - } - - if (h->bulkIn == 0) { - ERR("bulkIn endpoint not assigned\n"); - return -1; - } - - result = (*h->interface)->ReadPipe( - h->interface, h->bulkIn, data, &numBytes); - - if (result == 0) { - return (int) numBytes; - } else { - ERR("usb_read failed with status %x\n", result); - } - - return -1; -} - -int usb_write(usb_handle *h, const void *data, int len) { - IOReturn result; - - if (len == 0) { - return 0; - } - - if (h == NULL) { - return -1; - } - - if (h->interface == NULL) { - ERR("usb_write interface was null\n"); - return -1; - } - - if (h->bulkOut == 0) { - ERR("bulkOut endpoint not assigned\n"); - return -1; - } - - result = (*h->interface)->WritePipe( - h->interface, h->bulkOut, (void *)data, len); - - #if 0 - if ((result == 0) && (h->zero_mask)) { - /* we need 0-markers and our transfer */ - if(!(len & h->zero_mask)) { - result = (*h->interface)->WritePipe( - h->interface, h->bulkOut, (void *)data, 0); - } - } - #endif - - if (result != 0) { - ERR("usb_write failed with status %x\n", result); - return -1; - } - - return len; -} diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.c deleted file mode 100644 index 9c0a9cbf134aac419bf634865f284c1bcb4a9913..0000000000000000000000000000000000000000 --- a/fastboot/usb_windows.c +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <windows.h> -#include <winerror.h> -#include <errno.h> -#include <usb100.h> -#include <adb_api.h> -#include <stdio.h> - -#include "usb.h" - -//#define TRACE_USB 1 -#if TRACE_USB -#define DBG(x...) fprintf(stderr, x) -#else -#define DBG(x...) -#endif - - -/** Structure usb_handle describes our connection to the usb device via - AdbWinApi.dll. This structure is returned from usb_open() routine and - is expected in each subsequent call that is accessing the device. -*/ -struct usb_handle { - /// Handle to USB interface - ADBAPIHANDLE adb_interface; - - /// Handle to USB read pipe (endpoint) - ADBAPIHANDLE adb_read_pipe; - - /// Handle to USB write pipe (endpoint) - ADBAPIHANDLE adb_write_pipe; - - /// Interface name - char* interface_name; -}; - -/// Class ID assigned to the device by androidusb.sys -static const GUID usb_class_id = ANDROID_USB_CLASS_ID; - - -/// Checks if interface (device) matches certain criteria -int recognized_device(usb_handle* handle, ifc_match_func callback); - -/// Opens usb interface (device) by interface (device) name. -usb_handle* do_usb_open(const wchar_t* interface_name); - -/// Writes data to the opened usb handle -int usb_write(usb_handle* handle, const void* data, int len); - -/// Reads data using the opened usb handle -int usb_read(usb_handle *handle, void* data, int len); - -/// Cleans up opened usb handle -void usb_cleanup_handle(usb_handle* handle); - -/// Cleans up (but don't close) opened usb handle -void usb_kick(usb_handle* handle); - -/// Closes opened usb handle -int usb_close(usb_handle* handle); - - -usb_handle* do_usb_open(const wchar_t* interface_name) { - // Allocate our handle - usb_handle* ret = (usb_handle*)malloc(sizeof(usb_handle)); - if (NULL == ret) - return NULL; - - // Create interface. - ret->adb_interface = AdbCreateInterfaceByName(interface_name); - - if (NULL == ret->adb_interface) { - free(ret); - errno = GetLastError(); - return NULL; - } - - // Open read pipe (endpoint) - ret->adb_read_pipe = - AdbOpenDefaultBulkReadEndpoint(ret->adb_interface, - AdbOpenAccessTypeReadWrite, - AdbOpenSharingModeReadWrite); - if (NULL != ret->adb_read_pipe) { - // Open write pipe (endpoint) - ret->adb_write_pipe = - AdbOpenDefaultBulkWriteEndpoint(ret->adb_interface, - AdbOpenAccessTypeReadWrite, - AdbOpenSharingModeReadWrite); - if (NULL != ret->adb_write_pipe) { - // Save interface name - unsigned long name_len = 0; - - // First get expected name length - AdbGetInterfaceName(ret->adb_interface, - NULL, - &name_len, - true); - if (0 != name_len) { - ret->interface_name = (char*)malloc(name_len); - - if (NULL != ret->interface_name) { - // Now save the name - if (AdbGetInterfaceName(ret->adb_interface, - ret->interface_name, - &name_len, - true)) { - // We're done at this point - return ret; - } - } else { - SetLastError(ERROR_OUTOFMEMORY); - } - } - } - } - - // Something went wrong. - errno = GetLastError(); - usb_cleanup_handle(ret); - free(ret); - SetLastError(errno); - - return NULL; -} - -int usb_write(usb_handle* handle, const void* data, int len) { - unsigned long time_out = 500 + len * 8; - unsigned long written = 0; - unsigned count = 0; - int ret; - - DBG("usb_write %d\n", len); - if (NULL != handle) { - // Perform write - while(len > 0) { - int xfer = (len > 4096) ? 4096 : len; - ret = AdbWriteEndpointSync(handle->adb_write_pipe, - (void*)data, - (unsigned long)xfer, - &written, - time_out); - errno = GetLastError(); - DBG("AdbWriteEndpointSync returned %d, errno: %d\n", ret, errno); - if (ret == 0) { - // assume ERROR_INVALID_HANDLE indicates we are disconnected - if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle); - return -1; - } - - count += written; - len -= written; - data += written; - - if (len == 0) - return count; - } - } else { - DBG("usb_write NULL handle\n"); - SetLastError(ERROR_INVALID_HANDLE); - } - - DBG("usb_write failed: %d\n", errno); - - return -1; -} - -int usb_read(usb_handle *handle, void* data, int len) { - unsigned long time_out = 500 + len * 8; - unsigned long read = 0; - int ret; - - DBG("usb_read %d\n", len); - if (NULL != handle) { - while (1) { - int xfer = (len > 4096) ? 4096 : len; - - ret = AdbReadEndpointSync(handle->adb_read_pipe, - (void*)data, - (unsigned long)xfer, - &read, - time_out); - errno = GetLastError(); - DBG("usb_read got: %ld, expected: %d, errno: %d\n", read, xfer, errno); - if (ret) { - return read; - } else if (errno != ERROR_SEM_TIMEOUT) { - // assume ERROR_INVALID_HANDLE indicates we are disconnected - if (errno == ERROR_INVALID_HANDLE) - usb_kick(handle); - break; - } - // else we timed out - try again - } - } else { - DBG("usb_read NULL handle\n"); - SetLastError(ERROR_INVALID_HANDLE); - } - - DBG("usb_read failed: %d\n", errno); - - return -1; -} - -void usb_cleanup_handle(usb_handle* handle) { - if (NULL != handle) { - if (NULL != handle->interface_name) - free(handle->interface_name); - if (NULL != handle->adb_write_pipe) - AdbCloseHandle(handle->adb_write_pipe); - if (NULL != handle->adb_read_pipe) - AdbCloseHandle(handle->adb_read_pipe); - if (NULL != handle->adb_interface) - AdbCloseHandle(handle->adb_interface); - - handle->interface_name = NULL; - handle->adb_write_pipe = NULL; - handle->adb_read_pipe = NULL; - handle->adb_interface = NULL; - } -} - -void usb_kick(usb_handle* handle) { - if (NULL != handle) { - usb_cleanup_handle(handle); - } else { - SetLastError(ERROR_INVALID_HANDLE); - errno = ERROR_INVALID_HANDLE; - } -} - -int usb_close(usb_handle* handle) { - DBG("usb_close\n"); - - if (NULL != handle) { - // Cleanup handle - usb_cleanup_handle(handle); - free(handle); - } - - return 0; -} - -int recognized_device(usb_handle* handle, ifc_match_func callback) { - struct usb_ifc_info info; - USB_DEVICE_DESCRIPTOR device_desc; - USB_INTERFACE_DESCRIPTOR interf_desc; - - if (NULL == handle) - return 0; - - // Check vendor and product id first - if (!AdbGetUsbDeviceDescriptor(handle->adb_interface, - &device_desc)) { - return 0; - } - - // Then check interface properties - if (!AdbGetUsbInterfaceDescriptor(handle->adb_interface, - &interf_desc)) { - return 0; - } - - // Must have two endpoints - if (2 != interf_desc.bNumEndpoints) { - return 0; - } - - info.dev_vendor = device_desc.idVendor; - info.dev_product = device_desc.idProduct; - info.dev_class = device_desc.bDeviceClass; - info.dev_subclass = device_desc.bDeviceSubClass; - info.dev_protocol = device_desc.bDeviceProtocol; - info.ifc_class = interf_desc.bInterfaceClass; - info.ifc_subclass = interf_desc.bInterfaceSubClass; - info.ifc_protocol = interf_desc.bInterfaceProtocol; - - // read serial number (if there is one) - unsigned long serial_number_len = sizeof(info.serial_number); - if (!AdbGetSerialNumber(handle->adb_interface, info.serial_number, - &serial_number_len, true)) { - info.serial_number[0] = 0; - } - - if (callback(&info) == 0) { - return 1; - } - - return 0; -} - -static usb_handle *find_usb_device(ifc_match_func callback) { - usb_handle* handle = NULL; - char entry_buffer[2048]; - char interf_name[2048]; - AdbInterfaceInfo* next_interface = (AdbInterfaceInfo*)(&entry_buffer[0]); - unsigned long entry_buffer_size = sizeof(entry_buffer); - char* copy_name; - - // Enumerate all present and active interfaces. - ADBAPIHANDLE enum_handle = - AdbEnumInterfaces(usb_class_id, true, true, true); - - if (NULL == enum_handle) - return NULL; - - while (AdbNextInterface(enum_handle, next_interface, &entry_buffer_size)) { - // TODO(vchtchetkine): FIXME - temp hack converting wchar_t into char. - // It would be better to change AdbNextInterface so it will return - // interface name as single char string. - const wchar_t* wchar_name = next_interface->device_name; - for(copy_name = interf_name; - L'\0' != *wchar_name; - wchar_name++, copy_name++) { - *copy_name = (char)(*wchar_name); - } - *copy_name = '\0'; - - handle = do_usb_open(next_interface->device_name); - if (NULL != handle) { - // Lets see if this interface (device) belongs to us - if (recognized_device(handle, callback)) { - // found it! - break; - } else { - usb_cleanup_handle(handle); - free(handle); - handle = NULL; - } - } - - entry_buffer_size = sizeof(entry_buffer); - } - - AdbCloseHandle(enum_handle); - return handle; -} - -usb_handle *usb_open(ifc_match_func callback) -{ - return find_usb_device(callback); -} - -// called from fastboot.c -void sleep(int seconds) -{ - Sleep(seconds * 1000); -} diff --git a/fastboot/usbtest.c b/fastboot/usbtest.c deleted file mode 100644 index e34d7e625830120840b113d109529c8c59c37b54..0000000000000000000000000000000000000000 --- a/fastboot/usbtest.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#include <sys/time.h> - -#include "usb.h" - -static unsigned arg_size = 4096; -static unsigned arg_count = 4096; - -long long NOW(void) -{ - struct timeval tv; - gettimeofday(&tv, 0); - - return (((long long) tv.tv_sec) * ((long long) 1000000)) + - (((long long) tv.tv_usec)); -} - -int printifc(usb_ifc_info *info) -{ - printf("dev: csp=%02x/%02x/%02x v=%04x p=%04x ", - info->dev_class, info->dev_subclass, info->dev_protocol, - info->dev_vendor, info->dev_product); - printf("ifc: csp=%02x/%02x/%02x%s%s\n", - info->ifc_class, info->ifc_subclass, info->ifc_protocol, - info->has_bulk_in ? " in" : "", - info->has_bulk_out ? " out" : ""); - return -1; -} - -int match_null(usb_ifc_info *info) -{ - if(info->dev_vendor != 0x18d1) return -1; - if(info->ifc_class != 0xff) return -1; - if(info->ifc_subclass != 0xfe) return -1; - if(info->ifc_protocol != 0x01) return -1; - return 0; -} - -int match_zero(usb_ifc_info *info) -{ - if(info->dev_vendor != 0x18d1) return -1; - if(info->ifc_class != 0xff) return -1; - if(info->ifc_subclass != 0xfe) return -1; - if(info->ifc_protocol != 0x02) return -1; - return 0; -} - -int match_loop(usb_ifc_info *info) -{ - if(info->dev_vendor != 0x18d1) return -1; - if(info->ifc_class != 0xff) return -1; - if(info->ifc_subclass != 0xfe) return -1; - if(info->ifc_protocol != 0x03) return -1; - return 0; -} - -int test_null(usb_handle *usb) -{ - int i; - unsigned char buf[4096]; - memset(buf, 0xee, 4096); - long long t0, t1; - - t0 = NOW(); - for(i = 0; i < arg_count; i++) { - if(usb_write(usb, buf, arg_size) != arg_size) { - fprintf(stderr,"write failed (%s)\n", strerror(errno)); - return -1; - } - } - t1 = NOW(); - fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0)); - return 0; -} - -int test_zero(usb_handle *usb) -{ - int i; - unsigned char buf[4096]; - long long t0, t1; - - t0 = NOW(); - for(i = 0; i < arg_count; i++) { - if(usb_read(usb, buf, arg_size) != arg_size) { - fprintf(stderr,"read failed (%s)\n", strerror(errno)); - return -1; - } - } - t1 = NOW(); - fprintf(stderr,"%d bytes in %lld uS\n", arg_count * arg_size, (t1 - t0)); - return 0; -} - -struct -{ - const char *cmd; - ifc_match_func match; - int (*test)(usb_handle *usb); - const char *help; -} tests[] = { - { "list", printifc, 0, "list interfaces" }, - { "send", match_null, test_null, "send to null interface" }, - { "recv", match_zero, test_zero, "recv from zero interface" }, - { "loop", match_loop, 0, "exercise loopback interface" }, - {}, -}; - -int usage(void) -{ - int i; - - fprintf(stderr,"usage: usbtest <testname>\n\navailable tests:\n"); - for(i = 0; tests[i].cmd; i++) { - fprintf(stderr," %-8s %s\n", tests[i].cmd, tests[i].help); - } - return -1; -} - -int process_args(int argc, char **argv) -{ - while(argc-- > 0) { - char *arg = *argv++; - if(!strncmp(arg,"count=",6)) { - arg_count = atoi(arg + 6); - } else if(!strncmp(arg,"size=",5)) { - arg_size = atoi(arg + 5); - } else { - fprintf(stderr,"unknown argument: %s\n", arg); - return -1; - } - } - - if(arg_count == 0) { - fprintf(stderr,"count may not be zero\n"); - return -1; - } - - if(arg_size > 4096) { - fprintf(stderr,"size may not be greater than 4096\n"); - return -1; - } - - return 0; -} - -int main(int argc, char **argv) -{ - usb_handle *usb; - int i; - - if(argc < 2) - return usage(); - - if(argc > 2) { - if(process_args(argc - 2, argv + 2)) - return -1; - } - - for(i = 0; tests[i].cmd; i++) { - if(!strcmp(argv[1], tests[i].cmd)) { - usb = usb_open(tests[i].match); - if(tests[i].test) { - if(usb == 0) { - fprintf(stderr,"usbtest: %s: could not find interface\n", - tests[i].cmd); - return -1; - } - if(tests[i].test(usb)) { - fprintf(stderr,"usbtest: %s: FAIL\n", tests[i].cmd); - return -1; - } else { - fprintf(stderr,"usbtest: %s: OKAY\n", tests[i].cmd); - } - } - return 0; - } - } - - return usage(); -} diff --git a/fastboot/util_linux.c b/fastboot/util_linux.c deleted file mode 100644 index 912e16f98d570f6e3c573dc7d2c0cff78ec50dc3..0000000000000000000000000000000000000000 --- a/fastboot/util_linux.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <limits.h> - -void get_my_path(char *path) -{ - char proc[64]; - char *x; - - sprintf(proc, "/proc/%d/exe", getpid()); - int err = readlink(proc, path, PATH_MAX - 1); - - if(err <= 0) { - path[0] = 0; - } else { - path[err] = 0; - x = strrchr(path,'/'); - if(x) x[1] = 0; - } -} diff --git a/fastboot/util_osx.c b/fastboot/util_osx.c deleted file mode 100644 index 068241cef88c6341881825b83ea60371c1533d7a..0000000000000000000000000000000000000000 --- a/fastboot/util_osx.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <utils/executablepath.h> -#import <Carbon/Carbon.h> -#include <unistd.h> - -void get_my_path(char s[PATH_MAX]) -{ - char *x; - ProcessSerialNumber psn; - GetCurrentProcess(&psn); - CFDictionaryRef dict; - dict = ProcessInformationCopyDictionary(&psn, 0xffffffff); - CFStringRef value = (CFStringRef)CFDictionaryGetValue(dict, - CFSTR("CFBundleExecutable")); - CFStringGetCString(value, s, PATH_MAX - 1, kCFStringEncodingUTF8); - x = strrchr(s, '/'); - if(x) x[1] = 0; -} - - diff --git a/fastboot/util_windows.c b/fastboot/util_windows.c deleted file mode 100644 index 37077a498447c2d749921ad7163997e952aecbb6..0000000000000000000000000000000000000000 --- a/fastboot/util_windows.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <unistd.h> -#include <limits.h> - -#include <windows.h> - -void get_my_path(char exe[PATH_MAX]) -{ - char* r; - - GetModuleFileName( NULL, exe, PATH_MAX-1 ); - exe[PATH_MAX-1] = 0; - r = strrchr( exe, '\\' ); - if (r) - *r = 0; -} - - -void *load_file(const char *fn, unsigned *_sz) -{ - HANDLE file; - char *data; - DWORD file_size; - - file = CreateFile( fn, - GENERIC_READ, - FILE_SHARE_READ, - NULL, - OPEN_EXISTING, - 0, - NULL ); - - if (file == INVALID_HANDLE_VALUE) - return NULL; - - file_size = GetFileSize( file, NULL ); - data = NULL; - - if (file_size > 0) { - data = (char*) malloc( file_size ); - if (data == NULL) { - fprintf(stderr, "load_file: could not allocate %ld bytes\n", file_size ); - file_size = 0; - } else { - DWORD out_bytes; - - if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) || - out_bytes != file_size ) - { - fprintf(stderr, "load_file: could not read %ld bytes from '%s'\n", file_size, fn); - free(data); - data = NULL; - file_size = 0; - } - } - } - CloseHandle( file ); - - *_sz = (unsigned) file_size; - return data; -} diff --git a/include/arch/darwin-x86/AndroidConfig.h b/include/arch/darwin-x86/AndroidConfig.h deleted file mode 100644 index 49f04e51454825312023501551c4c3a1b4433e5e..0000000000000000000000000000000000000000 --- a/include/arch/darwin-x86/AndroidConfig.h +++ /dev/null @@ -1,260 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Android config -- "Darwin". Used for PPC Mac OS X. - * - * TODO: split this into "x86" and "ppc" versions - */ -#ifndef _ANDROID_CONFIG_H -#define _ANDROID_CONFIG_H - -/* - * =========================================================================== - * !!! IMPORTANT !!! - * =========================================================================== - * - * This file is included by ALL C/C++ source files. Don't put anything in - * here unless you are absolutely certain it can't go anywhere else. - * - * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" - * comments. - */ - -/* - * Threading model. Choose one: - * - * HAVE_PTHREADS - use the pthreads library. - * HAVE_WIN32_THREADS - use Win32 thread primitives. - * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX - */ -#define HAVE_PTHREADS - -/* - * Do we have the futex syscall? - */ - -/* #define HAVE_FUTEX */ - -/* - * Process creation model. Choose one: - * - * HAVE_FORKEXEC - use fork() and exec() - * HAVE_WIN32_PROC - use CreateProcess() - */ -#define HAVE_FORKEXEC - -/* - * Process out-of-memory adjustment. Set if running on Linux, - * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory - * badness adjustment. - */ -/* #define HAVE_OOM_ADJ */ - -/* - * IPC model. Choose one: - * - * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). - * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). - * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). - * HAVE_ANDROID_IPC - use Android versions (?, mmap). - */ -#define HAVE_MACOSX_IPC - -/* - * Memory-mapping model. Choose one: - * - * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h - * HAVE_WIN32_FILEMAP - use Win32 filemaps - */ -#define HAVE_POSIX_FILEMAP - -/* - * Define this if you have <termio.h> - */ -#define HAVE_TERMIO_H - -/* - * Define this if you build against MSVCRT.DLL - */ -/* #define HAVE_MS_C_RUNTIME */ - -/* - * Define this if you have sys/uio.h - */ -#define HAVE_SYS_UIO_H - -/* - * Define this if your platforms implements symbolic links - * in its filesystems - */ -#define HAVE_SYMLINKS - -/* - * Define this if we have localtime_r(). - */ -#define HAVE_LOCALTIME_R - -/* - * Define this if we have gethostbyname_r(). - */ -/* #define HAVE_GETHOSTBYNAME_R */ - -/* - * Define this if we have ioctl(). - */ -/* #define HAVE_IOCTL */ - -/* - * Define this if we want to use WinSock. - */ -/* #define HAVE_WINSOCK */ - -/* - * Define this if have clock_gettime() and friends - */ -/* #define HAVE_POSIX_CLOCKS */ - -/* - * Define this if we have pthread_cond_timedwait_monotonic() and - * clock_gettime(CLOCK_MONOTONIC). - */ -/* #define HAVE_TIMEDWAIT_MONOTONIC */ - -/* - * Endianness of the target machine. Choose one: - * - * HAVE_ENDIAN_H -- have endian.h header we can include. - * HAVE_LITTLE_ENDIAN -- we are little endian. - * HAVE_BIG_ENDIAN -- we are big endian. - */ -#if (defined(__ppc__) || defined(__ppc64__)) -# define HAVE_BIG_ENDIAN -#elif defined(__i386__) -# define HAVE_LITTLE_ENDIAN -#endif - -/* - * We need to choose between 32-bit and 64-bit off_t. All of our code should - * agree on the same size. For desktop systems, use 64-bit values, - * because some of our libraries (e.g. wxWidgets) expect to be built that way. - */ -#define _FILE_OFFSET_BITS 64 -#define _LARGEFILE_SOURCE 1 - -/* - * Defined if we have the backtrace() call for retrieving a stack trace. - * Needed for CallStack to operate; if not defined, CallStack is - * non-functional. - */ -#define HAVE_BACKTRACE 0 - -/* - * Defined if we have the dladdr() call for retrieving the symbol associated - * with a memory address. If not defined, stack crawls will not have symbolic - * information. - */ -#define HAVE_DLADDR 0 - -/* - * Defined if we have the cxxabi.h header for demangling C++ symbols. If - * not defined, stack crawls will be displayed with raw mangled symbols - */ -#define HAVE_CXXABI 0 - -/* - * Defined if we have the gettid() system call. - */ -/* #define HAVE_GETTID */ - - -/* - * Add any extra platform-specific defines here. - */ -#define _THREAD_SAFE - -/* - * Define if we have <malloc.h> header - */ -/* #define HAVE_MALLOC_H */ - -/* - * Define if tm struct has tm_gmtoff field - */ -#define HAVE_TM_GMTOFF 1 - -/* - * Define if dirent struct has d_type field - */ -#define HAVE_DIRENT_D_TYPE 1 - -/* - * Define if we have madvise() in <sys/mman.h> - */ -#define HAVE_MADVISE 1 - -/* - * Define if we include <sys/mount.h> for statfs() - */ -#define INCLUDE_SYS_MOUNT_FOR_STATFS 1 - -/* - * What CPU architecture does this platform use? - */ -#if (defined(__ppc__) || defined(__ppc64__)) -# define ARCH_PPC -#elif defined(__i386__) -# define ARCH_X86 -#endif - -/* - * sprintf() format string for shared library naming. - */ -#define OS_SHARED_LIB_FORMAT_STR "lib%s.dylib" - -/* - * type for the third argument to mincore(). - */ -#define MINCORE_POINTER_TYPE char * - -/* - * The default path separator for the platform - */ -#define OS_PATH_SEPARATOR '/' - -/* - * Is the filesystem case sensitive? - * - * For tools apps, we'll treat is as not case sensitive. - */ -/* #define OS_CASE_SENSITIVE */ - -/* - * Define if <sys/socket.h> exists. - */ -#define HAVE_SYS_SOCKET_H 1 - -/* - * Define if the strlcpy() function exists on the system. - */ -#define HAVE_STRLCPY 1 - -/* - * Define if writev() exists - */ -#define HAVE_WRITEV 1 - -#endif /*_ANDROID_CONFIG_H*/ diff --git a/include/arch/linux-arm/AndroidConfig.h b/include/arch/linux-arm/AndroidConfig.h deleted file mode 100644 index f3221274922d8c6419b93f6ef94bda1c1e06ff83..0000000000000000000000000000000000000000 --- a/include/arch/linux-arm/AndroidConfig.h +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Android config -- "android-arm". Used for ARM device builds. - */ -#ifndef _ANDROID_CONFIG_H -#define _ANDROID_CONFIG_H - -/* - * =========================================================================== - * !!! IMPORTANT !!! - * =========================================================================== - * - * This file is included by ALL C/C++ source files. Don't put anything in - * here unless you are absolutely certain it can't go anywhere else. - * - * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" - * comments. - */ - -/* - * Threading model. Choose one: - * - * HAVE_PTHREADS - use the pthreads library. - * HAVE_WIN32_THREADS - use Win32 thread primitives. - * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX - */ -#define HAVE_PTHREADS - -/* - * Do we have the futex syscall? - */ - -#define HAVE_FUTEX - -/* - * Define if we already have the futex wrapper functions defined. Yes if - * compiling against bionic. - */ -#define HAVE_FUTEX_WRAPPERS 1 - -/* - * Process creation model. Choose one: - * - * HAVE_FORKEXEC - use fork() and exec() - * HAVE_WIN32_PROC - use CreateProcess() - */ -#define HAVE_FORKEXEC - -/* - * Process out-of-memory adjustment. Set if running on Linux, - * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory - * badness adjustment. - */ -#define HAVE_OOM_ADJ - -/* - * IPC model. Choose one: - * - * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). - * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). - * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). - * HAVE_ANDROID_IPC - use Android versions (?, mmap). - */ -#define HAVE_ANDROID_IPC - -/* - * Memory-mapping model. Choose one: - * - * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h - * HAVE_WIN32_FILEMAP - use Win32 filemaps - */ -#define HAVE_POSIX_FILEMAP - -/* - * Define this if you have <termio.h> - */ -#define HAVE_TERMIO_H - -/* - * Define this if you build against MSVCRT.DLL - */ -/* #define HAVE_MS_C_RUNTIME */ - -/* - * Define this if you have sys/uio.h - */ -#define HAVE_SYS_UIO_H - -/* - * Define this if your platforms implements symbolic links - * in its filesystems - */ -#define HAVE_SYMLINKS - -/* - * Define this if we have localtime_r(). - */ -/* #define HAVE_LOCALTIME_R */ - -/* - * Define this if we have gethostbyname_r(). - */ -/* #define HAVE_GETHOSTBYNAME_R */ - -/* - * Define this if we have ioctl(). - */ -#define HAVE_IOCTL - -/* - * Define this if we want to use WinSock. - */ -/* #define HAVE_WINSOCK */ - -/* - * Define this if have clock_gettime() and friends - */ -#define HAVE_POSIX_CLOCKS - -/* - * Define this if we have pthread_cond_timedwait_monotonic() and - * clock_gettime(CLOCK_MONOTONIC). - */ -#define HAVE_TIMEDWAIT_MONOTONIC - -/* - * Define this if we have linux style epoll() - */ -#define HAVE_EPOLL - -/* - * Endianness of the target machine. Choose one: - * - * HAVE_ENDIAN_H -- have endian.h header we can include. - * HAVE_LITTLE_ENDIAN -- we are little endian. - * HAVE_BIG_ENDIAN -- we are big endian. - */ -#define HAVE_ENDIAN_H -#define HAVE_LITTLE_ENDIAN - -/* - * We need to choose between 32-bit and 64-bit off_t. All of our code should - * agree on the same size. For desktop systems, use 64-bit values, - * because some of our libraries (e.g. wxWidgets) expect to be built that way. - */ -/* #define _FILE_OFFSET_BITS 64 */ -/* #define _LARGEFILE_SOURCE 1 */ - -/* - * Defined if we have the backtrace() call for retrieving a stack trace. - * Needed for CallStack to operate; if not defined, CallStack is - * non-functional. - */ -#define HAVE_BACKTRACE 0 - -/* - * Defined if we have the dladdr() call for retrieving the symbol associated - * with a memory address. If not defined, stack crawls will not have symbolic - * information. - */ -#define HAVE_DLADDR 0 - -/* - * Defined if we have the cxxabi.h header for demangling C++ symbols. If - * not defined, stack crawls will be displayed with raw mangled symbols - */ -#define HAVE_CXXABI 0 - -/* - * Defined if we have the gettid() system call. - */ -#define HAVE_GETTID - -/* - * Defined if we have the sched_setscheduler() call - */ -#define HAVE_SCHED_SETSCHEDULER - -/* - * Add any extra platform-specific defines here. - */ -#define __linux__ - -/* - * Define if we have <malloc.h> header - */ -#define HAVE_MALLOC_H - -/* - * Define if we're running on *our* linux on device or emulator. - */ -#define HAVE_ANDROID_OS 1 - -/* - * Define if we have Linux-style non-filesystem Unix Domain Sockets - */ -#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1 - -/* - * Define if we have Linux's inotify in <sys/inotify.h>. - */ -#define HAVE_INOTIFY 1 - -/* - * Define if we have madvise() in <sys/mman.h> - */ -#define HAVE_MADVISE 1 - -/* - * Define if tm struct has tm_gmtoff field - */ -#define HAVE_TM_GMTOFF 1 - -/* - * Define if dirent struct has d_type field - */ -#define HAVE_DIRENT_D_TYPE 1 - -/* - * Define if libc includes Android system properties implementation. - */ -#define HAVE_LIBC_SYSTEM_PROPERTIES 1 - -/* - * Define if system provides a system property server (should be - * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES). - */ -/* #define HAVE_SYSTEM_PROPERTY_SERVER */ - -/* - * What CPU architecture does this platform use? - */ -#define ARCH_ARM - -/* - * Define if the size of enums is as short as possible, - */ -/* #define HAVE_SHORT_ENUMS */ - -/* - * sprintf() format string for shared library naming. - */ -#define OS_SHARED_LIB_FORMAT_STR "lib%s.so" - -/* - * Do we have __memcmp16()? - */ -#define HAVE__MEMCMP16 1 - -/* - * type for the third argument to mincore(). - */ -#define MINCORE_POINTER_TYPE unsigned char * - -/* - * Do we have the sigaction flag SA_NOCLDWAIT? - */ -#define HAVE_SA_NOCLDWAIT - -/* - * The default path separator for the platform - */ -#define OS_PATH_SEPARATOR '/' - -/* - * Is the filesystem case sensitive? - */ -#define OS_CASE_SENSITIVE - -/* - * Define if <sys/socket.h> exists. - */ -#define HAVE_SYS_SOCKET_H 1 - -/* - * Define if the strlcpy() function exists on the system. - */ -#define HAVE_STRLCPY 1 - -/* - * Define if prctl() exists - */ -#define HAVE_PRCTL 1 - -/* - * Define if writev() exists - */ -#define HAVE_WRITEV 1 - -#endif /* _ANDROID_CONFIG_H */ diff --git a/include/arch/linux-x86/AndroidConfig.h b/include/arch/linux-x86/AndroidConfig.h deleted file mode 100644 index 6de75f8d1bc10e312a53a02a1bf0a35428d4cd63..0000000000000000000000000000000000000000 --- a/include/arch/linux-x86/AndroidConfig.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Android config -- "Linux". Used for desktop x86 Linux. - */ -#ifndef _ANDROID_CONFIG_H -#define _ANDROID_CONFIG_H - -/* - * =========================================================================== - * !!! IMPORTANT !!! - * =========================================================================== - * - * This file is included by ALL C/C++ source files. Don't put anything in - * here unless you are absolutely certain it can't go anywhere else. - * - * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" - * comments. - */ - -/* - * Threading model. Choose one: - * - * HAVE_PTHREADS - use the pthreads library. - * HAVE_WIN32_THREADS - use Win32 thread primitives. - * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX - */ -#define HAVE_PTHREADS - -/* - * Do we have the futex syscall? - */ - -#define HAVE_FUTEX - -/* - * Process creation model. Choose one: - * - * HAVE_FORKEXEC - use fork() and exec() - * HAVE_WIN32_PROC - use CreateProcess() - */ -#define HAVE_FORKEXEC - -/* - * Process out-of-memory adjustment. Set if running on Linux, - * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory - * badness adjustment. - */ -#define HAVE_OOM_ADJ - -/* - * IPC model. Choose one: - * - * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). - * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). - * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). - * HAVE_ANDROID_IPC - use Android versions (?, mmap). - */ -#define HAVE_SYSV_IPC - -/* - * Memory-mapping model. Choose one: - * - * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h - * HAVE_WIN32_FILEMAP - use Win32 filemaps - */ -#define HAVE_POSIX_FILEMAP - -/* - * Define this if you have <termio.h> - */ -#define HAVE_TERMIO_H - -/* - * Define this if you build against MSVCRT.DLL - */ -/* #define HAVE_MS_C_RUNTIME */ - -/* - * Define this if you have sys/uio.h - */ -#define HAVE_SYS_UIO_H - -/* - * Define this if your platforms implements symbolic links - * in its filesystems - */ -#define HAVE_SYMLINKS - -/* - * Define this if we have localtime_r(). - */ -#define HAVE_LOCALTIME_R - -/* - * Define this if we have gethostbyname_r(). - */ -#define HAVE_GETHOSTBYNAME_R - -/* - * Define this if we have ioctl(). - */ -#define HAVE_IOCTL - -/* - * Define this if we want to use WinSock. - */ -/* #define HAVE_WINSOCK */ - -/* - * Define this if have clock_gettime() and friends - * - * Desktop Linux has this in librt, but it's broken in goobuntu, yielding - * mildly or wildly inaccurate results. - */ -/*#define HAVE_POSIX_CLOCKS*/ - -/* - * Define this if we have pthread_cond_timedwait_monotonic() and - * clock_gettime(CLOCK_MONOTONIC). - */ -/* #define HAVE_TIMEDWAIT_MONOTONIC */ - -/* - * Define this if we have linux style epoll() - */ -#define HAVE_EPOLL - -/* - * Endianness of the target machine. Choose one: - * - * HAVE_ENDIAN_H -- have endian.h header we can include. - * HAVE_LITTLE_ENDIAN -- we are little endian. - * HAVE_BIG_ENDIAN -- we are big endian. - */ -#define HAVE_ENDIAN_H -#define HAVE_LITTLE_ENDIAN - -/* - * We need to choose between 32-bit and 64-bit off_t. All of our code should - * agree on the same size. For desktop systems, use 64-bit values, - * because some of our libraries (e.g. wxWidgets) expect to be built that way. - */ -#define _FILE_OFFSET_BITS 64 -#define _LARGEFILE_SOURCE 1 - -/* - * Defined if we have the backtrace() call for retrieving a stack trace. - * Needed for CallStack to operate; if not defined, CallStack is - * non-functional. - */ -#define HAVE_BACKTRACE 1 - -/* - * Defined if we have the dladdr() call for retrieving the symbol associated - * with a memory address. If not defined, stack crawls will not have symbolic - * information. - */ -#define HAVE_DLADDR 1 - -/* - * Defined if we have the cxxabi.h header for demangling C++ symbols. If - * not defined, stack crawls will be displayed with raw mangled symbols - */ -#define HAVE_CXXABI 0 - -/* - * Defined if we have the gettid() system call. - */ -/* #define HAVE_GETTID */ - -/* - * Defined if we have the sched_setscheduler() call - */ -#define HAVE_SCHED_SETSCHEDULER - -/* - * Add any extra platform-specific defines here. - */ - -/* - * Define if we have <malloc.h> header - */ -#define HAVE_MALLOC_H - -/* - * Define if we have Linux-style non-filesystem Unix Domain Sockets - */ - -/* - * What CPU architecture does this platform use? - */ -#define ARCH_X86 - - -/* - * Define if we have Linux's inotify in <sys/inotify.h>. - */ -/*#define HAVE_INOTIFY 1*/ - -/* - * Define if we have madvise() in <sys/mman.h> - */ -#define HAVE_MADVISE 1 - -/* - * Define if tm struct has tm_gmtoff field - */ -#define HAVE_TM_GMTOFF 1 - -/* - * Define if dirent struct has d_type field - */ -#define HAVE_DIRENT_D_TYPE 1 - -/* - * Define if libc includes Android system properties implementation. - */ -/* #define HAVE_LIBC_SYSTEM_PROPERTIES */ - -/* - * Define if system provides a system property server (should be - * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES). - */ -#define HAVE_SYSTEM_PROPERTY_SERVER - -/* - * sprintf() format string for shared library naming. - */ -#define OS_SHARED_LIB_FORMAT_STR "lib%s.so" - -/* - * type for the third argument to mincore(). - */ -#define MINCORE_POINTER_TYPE unsigned char * - -/* - * Do we have the sigaction flag SA_NOCLDWAIT? - */ -#define HAVE_SA_NOCLDWAIT - -/* - * The default path separator for the platform - */ -#define OS_PATH_SEPARATOR '/' - -/* - * Is the filesystem case sensitive? - */ -#define OS_CASE_SENSITIVE - -/* - * Define if <sys/socket.h> exists. - */ -#define HAVE_SYS_SOCKET_H 1 - -/* - * Define if the strlcpy() function exists on the system. - */ -/* #define HAVE_STRLCPY 1 */ - -/* - * Define if prctl() exists - */ -#define HAVE_PRCTL 1 - -/* - * Define if writev() exists - */ -#define HAVE_WRITEV 1 - -#endif /*_ANDROID_CONFIG_H*/ diff --git a/include/arch/target_linux-x86/AndroidConfig.h b/include/arch/target_linux-x86/AndroidConfig.h deleted file mode 100644 index 4aa44f8835c73295edeba8fdd3405b06bbedb2fd..0000000000000000000000000000000000000000 --- a/include/arch/target_linux-x86/AndroidConfig.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Copyright 2005 The Android Open Source Project - * - * Android config -- "target_linux-x86". Used for x86 linux target devices. - */ -#ifndef _ANDROID_CONFIG_H -#define _ANDROID_CONFIG_H - -/* - * =========================================================================== - * !!! IMPORTANT !!! - * =========================================================================== - * - * This file is included by ALL C/C++ source files. Don't put anything in - * here unless you are absolutely certain it can't go anywhere else. - * - * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" - * comments. - */ - -/* - * Threading model. Choose one: - * - * HAVE_PTHREADS - use the pthreads library. - * HAVE_WIN32_THREADS - use Win32 thread primitives. - * -- combine HAVE_CREATETHREAD, HAVE_CREATEMUTEX, and HAVE__BEGINTHREADEX - */ -#define HAVE_PTHREADS - -/* - * Do we have the futex syscall? - */ - -#define HAVE_FUTEX - -/* - * Define if we already have the futex wrapper functions defined. Yes if - * compiling against bionic. - */ -#define HAVE_FUTEX_WRAPPERS 1 - -/* - * Process creation model. Choose one: - * - * HAVE_FORKEXEC - use fork() and exec() - * HAVE_WIN32_PROC - use CreateProcess() - */ -#define HAVE_FORKEXEC - -/* - * Process out-of-memory adjustment. Set if running on Linux, - * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory - * badness adjustment. - */ -#define HAVE_OOM_ADJ - -/* - * IPC model. Choose one: - * - * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). - * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). - * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). - * HAVE_ANDROID_IPC - use Android versions (?, mmap). - */ -#define HAVE_ANDROID_IPC 1 - -/* - * Memory-mapping model. Choose one: - * - * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h - * HAVE_WIN32_FILEMAP - use Win32 filemaps - */ -#define HAVE_POSIX_FILEMAP 1 - -/* - * Define this if you have <termio.h> - */ -#define HAVE_TERMIO_H 1 - -/* - * Define this if you build against have Microsoft C runtime (MSVCRT.DLL) - */ -/* #define HAVE_MS_C_RUNTIME */ - -/* - * Define this if you have sys/uio.h - */ -#define HAVE_SYS_UIO_H 1 - -/* - * Define this if your platforms implements symbolic links - * in its filesystems - */ -#define HAVE_SYMLINKS 1 - -/* - * Define this if we have localtime_r(). - */ -/* #define HAVE_LOCALTIME_R */ - -/* - * Define this if we have gethostbyname_r(). - */ -/* #define HAVE_GETHOSTBYNAME_R */ - -/* - * Define this if we have ioctl(). - */ -#define HAVE_IOCTL - -/* - * Define this if we want to use WinSock. - */ -/* #define HAVE_WINSOCK */ - -/* - * Define this if have clock_gettime() and friends - * - */ -#define HAVE_POSIX_CLOCKS - -/* - * Define this if we have pthread_cond_timedwait_monotonic() and - * clock_gettime(CLOCK_MONOTONIC). - */ -#define HAVE_TIMEDWAIT_MONOTONIC - -/* - * Define this if we have linux style epoll() - */ -#define HAVE_EPOLL - -/* - * Endianness of the target machine. Choose one: - * - * HAVE_ENDIAN_H -- have endian.h header we can include. - * HAVE_LITTLE_ENDIAN -- we are little endian. - * HAVE_BIG_ENDIAN -- we are big endian. - */ -#define HAVE_ENDIAN_H -#define HAVE_LITTLE_ENDIAN - -/* - * We need to choose between 32-bit and 64-bit off_t. All of our code should - * agree on the same size. For desktop systems, use 64-bit values, - * because some of our libraries (e.g. wxWidgets) expect to be built that way. - */ -/* - * #define _FILE_OFFSET_BITS 64 - * #define _LARGEFILE_SOURCE 1 - */ - -/* - * Defined if we have the backtrace() call for retrieving a stack trace. - * Needed for CallStack to operate; if not defined, CallStack is - * non-functional. - */ -#define HAVE_BACKTRACE 0 - -/* - * Defined if we have the dladdr() call for retrieving the symbol associated - * with a memory address. If not defined, stack crawls will not have symbolic - * information. - */ -#define HAVE_DLADDR 0 - -/* - * Defined if we have the cxxabi.h header for demangling C++ symbols. If - * not defined, stack crawls will be displayed with raw mangled symbols - */ -#define HAVE_CXXABI 0 - -/* - * Defined if we have the gettid() system call. - */ -#define HAVE_GETTID - -/* - * Defined if we have the sched_setscheduler() call - */ -#define HAVE_SCHED_SETSCHEDULER - -/* - * Add any extra platform-specific defines here. - */ -#ifndef __linux__ -#define __linux__ -#endif - -/* - * Define if we have <malloc.h> header - */ -#define HAVE_MALLOC_H - -/* - * Define if we're running on *our* linux on device or emulator. - */ -#define HAVE_ANDROID_OS 1 - -/* - * Define if we have Linux-style non-filesystem Unix Domain Sockets - */ -#define HAVE_LINUX_LOCAL_SOCKET_NAMESPACE 1 - -/* - * Define if we have Linux's inotify in <sys/inotify.h>. - */ -#define HAVE_INOTIFY 1 - -/* - * Define if we have madvise() in <sys/mman.h> - */ -#define HAVE_MADVISE 1 - -/* - * Define if we have Linux's dbus - */ -#define HAVE_DBUS 1 - -/* - * Define if tm struct has tm_gmtoff field - */ -#define HAVE_TM_GMTOFF 1 - -/* - * Define if dirent struct has d_type field - */ -#define HAVE_DIRENT_D_TYPE 1 - -/* - * Define if libc includes Android system properties implementation. - */ -#define HAVE_LIBC_SYSTEM_PROPERTIES 1 - -/* - * Define if system provides a system property server (should be - * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES). - */ -/* #define HAVE_SYSTEM_PROPERTY_SERVER */ - -/* - * What CPU architecture does this platform use? - */ -#define ARCH_X86 - -/* - * sprintf() format string for shared library naming. - */ -#define OS_SHARED_LIB_FORMAT_STR "lib%s.so" - -/* - * Do we have __memcmp16()? - */ -/* #define HAVE__MEMCMP16 1 */ - -/* - * type for the third argument to mincore(). - */ -#define MINCORE_POINTER_TYPE unsigned char * - -/* - * Do we have the sigaction flag SA_NOCLDWAIT? - */ -#define HAVE_SA_NOCLDWAIT - -/* - * The default path separator for the platform - */ -#define OS_PATH_SEPARATOR '/' - -/* - * Is the filesystem case sensitive? - */ -#define OS_CASE_SENSITIVE - -/* - * Define if <sys/socket.h> exists. - */ -#define HAVE_SYS_SOCKET_H 1 - -/* - * Define if the strlcpy() function exists on the system. - */ -#define HAVE_STRLCPY 1 - -/* - * Define if prctl() exists - */ -#define HAVE_PRCTL 1 - -/* - * Whether or not _Unwind_Context is defined as a struct. - */ -#define HAVE_UNWIND_CONTEXT_STRUCT - -#endif /* _ANDROID_CONFIG_H */ diff --git a/include/arch/windows/AndroidConfig.h b/include/arch/windows/AndroidConfig.h deleted file mode 100644 index c3c6ff11d84c4deb659e5e757b9e9b2f5fa08c02..0000000000000000000000000000000000000000 --- a/include/arch/windows/AndroidConfig.h +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Android config -- "CYGWIN_NT-5.1". - * - * Cygwin has pthreads, but GDB seems to get confused if you use it to - * create threads. By "confused", I mean it freezes up the first time the - * debugged process creates a thread, even if you use CreateThread. The - * mere presence of pthreads linkage seems to cause problems. - */ -#ifndef _ANDROID_CONFIG_H -#define _ANDROID_CONFIG_H - -/* - * =========================================================================== - * !!! IMPORTANT !!! - * =========================================================================== - * - * This file is included by ALL C/C++ source files. Don't put anything in - * here unless you are absolutely certain it can't go anywhere else. - * - * Any C++ stuff must be wrapped with "#ifdef __cplusplus". Do not use "//" - * comments. - */ - -/* - * Threading model. Choose one: - * - * HAVE_PTHREADS - use the pthreads library. - * HAVE_WIN32_THREADS - use Win32 thread primitives. - */ -#define HAVE_WIN32_THREADS - -/* - * Do we have the futex syscall? - */ - -/* #define HAVE_FUTEX */ - - -/* - * Process creation model. Choose one: - * - * HAVE_FORKEXEC - use fork() and exec() - * HAVE_WIN32_PROC - use CreateProcess() - */ -#ifdef __CYGWIN__ -# define HAVE_FORKEXEC -#else -# define HAVE_WIN32_PROC -#endif - -/* - * Process out-of-memory adjustment. Set if running on Linux, - * where we can write to /proc/<pid>/oom_adj to modify the out-of-memory - * badness adjustment. - */ -/* #define HAVE_OOM_ADJ */ - -/* - * IPC model. Choose one: - * - * HAVE_SYSV_IPC - use the classic SysV IPC mechanisms (semget, shmget). - * HAVE_MACOSX_IPC - use Macintosh IPC mechanisms (sem_open, mmap). - * HAVE_WIN32_IPC - use Win32 IPC (CreateSemaphore, CreateFileMapping). - * HAVE_ANDROID_IPC - use Android versions (?, mmap). - */ -#define HAVE_WIN32_IPC - -/* - * Memory-mapping model. Choose one: - * - * HAVE_POSIX_FILEMAP - use the Posix sys/mmap.h - * HAVE_WIN32_FILEMAP - use Win32 filemaps - */ -#ifdef __CYGWIN__ -#define HAVE_POSIX_FILEMAP -#else -#define HAVE_WIN32_FILEMAP -#endif - -/* - * Define this if you have <termio.h> - */ -#ifdef __CYGWIN__ -# define HAVE_TERMIO_H -#endif - -/* - * Define this if you build against MSVCRT.DLL - */ -#ifndef __CYGWIN__ -# define HAVE_MS_C_RUNTIME -#endif - -/* - * Define this if you have sys/uio.h - */ -#ifdef __CYGWIN__ -#define HAVE_SYS_UIO_H -#endif - - -/* - * Define this if we have localtime_r(). - */ -/* #define HAVE_LOCALTIME_R */ - -/* - * Define this if we have gethostbyname_r(). - */ -/* #define HAVE_GETHOSTBYNAME_R */ - -/* - * Define this if we have ioctl(). - */ -/* #define HAVE_IOCTL */ - -/* - * Define this if we want to use WinSock. - */ -#ifndef __CYGWIN__ -#define HAVE_WINSOCK -#endif - -/* - * Define this if your platforms implements symbolic links - * in its filesystems - */ -/* #define HAVE_SYMLINKS */ - -/* - * Define this if have clock_gettime() and friends - */ -/* #define HAVE_POSIX_CLOCKS */ - -/* - * Endianness of the target machine. Choose one: - * - * HAVE_ENDIAN_H -- have endian.h header we can include. - * HAVE_LITTLE_ENDIAN -- we are little endian. - * HAVE_BIG_ENDIAN -- we are big endian. - */ -#ifdef __CYGWIN__ -#define HAVE_ENDIAN_H -#endif - -#define HAVE_LITTLE_ENDIAN - -/* - * We need to choose between 32-bit and 64-bit off_t. All of our code should - * agree on the same size. For desktop systems, use 64-bit values, - * because some of our libraries (e.g. wxWidgets) expect to be built that way. - */ -#define _FILE_OFFSET_BITS 64 -#define _LARGEFILE_SOURCE 1 - -/* - * Defined if we have the backtrace() call for retrieving a stack trace. - * Needed for CallStack to operate; if not defined, CallStack is - * non-functional. - */ -#define HAVE_BACKTRACE 0 - -/* - * Defined if we have the dladdr() call for retrieving the symbol associated - * with a memory address. If not defined, stack crawls will not have symbolic - * information. - */ -#define HAVE_DLADDR 0 - -/* - * Defined if we have the cxxabi.h header for demangling C++ symbols. If - * not defined, stack crawls will be displayed with raw mangled symbols - */ -#define HAVE_CXXABI 0 - -/* - * Define if tm struct has tm_gmtoff field - */ -/* #define HAVE_TM_GMTOFF 1 */ - -/* - * Define if dirent struct has d_type field - */ -/* #define HAVE_DIRENT_D_TYPE 1 */ - -/* - * Define if libc includes Android system properties implementation. - */ -/* #define HAVE_LIBC_SYSTEM_PROPERTIES */ - -/* - * Define if system provides a system property server (should be - * mutually exclusive with HAVE_LIBC_SYSTEM_PROPERTIES). - */ -/* #define HAVE_SYSTEM_PROPERTY_SERVER */ - -/* - * Define if we have madvise() in <sys/mman.h> - */ -/*#define HAVE_MADVISE 1*/ - -/* - * Add any extra platform-specific defines here. - */ -#define WIN32 1 /* stock Cygwin doesn't define these */ -#define _WIN32 1 -#define _WIN32_WINNT 0x0500 /* admit to using >= Win2K */ - -#define HAVE_WINDOWS_PATHS /* needed by simulator */ - -/* - * What CPU architecture does this platform use? - */ -#define ARCH_X86 - -/* - * sprintf() format string for shared library naming. - */ -#define OS_SHARED_LIB_FORMAT_STR "lib%s.dll" - -/* - * type for the third argument to mincore(). - */ -#define MINCORE_POINTER_TYPE unsigned char * - -/* - * The default path separator for the platform - */ -#define OS_PATH_SEPARATOR '\\' - -/* - * Is the filesystem case sensitive? - */ -/* #define OS_CASE_SENSITIVE */ - -/* - * Define if <sys/socket.h> exists. - * Cygwin has it, but not MinGW. - */ -#ifdef USE_MINGW -/* #define HAVE_SYS_SOCKET_H */ -#else -#define HAVE_SYS_SOCKET_H 1 -#endif - -/* - * Define if the strlcpy() function exists on the system. - */ -/* #define HAVE_STRLCPY 1 */ - -/* - * Define if <winsock2.h> exists. - * Only MinGW has it. - */ -#ifdef USE_MINGW -#define HAVE_WINSOCK2_H 1 -#else -/* #define HAVE_WINSOCK2_H */ -#endif - -/* - * Various definitions missing in MinGW - */ -#ifdef USE_MINGW -#define S_IRGRP 0 -#define sleep _sleep -#endif - -/* - * Define if writev() exists. - */ -/* #define HAVE_WRITEV */ - -#endif /*_ANDROID_CONFIG_H*/ diff --git a/include/ctest/ctest.h b/include/ctest/ctest.h deleted file mode 100644 index 1a83b20d6d54129676a79910604a258447abf46b..0000000000000000000000000000000000000000 --- a/include/ctest/ctest.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Very simple unit testing framework. - */ - -#ifndef __CUTILS_TEST_H -#define __CUTILS_TEST_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Adds a test to the test suite. - */ -#define addTest(test) addNamedTest(#test, &test) - -/** - * Asserts that a condition is true. The test fails if it isn't. - */ -#define assertTrue(value, message) assertTrueWithSource(value, __FILE__, __LINE__, message); - -/** - * Asserts that a condition is false. The test fails if the value is true. - */ -#define assertFalse(value, message) assertTrueWithSource(!value, __FILE__, __LINE__, message); - -/** Fails a test with the given message. */ -#define fail(message) assertTrueWithSource(0, __FILE__, __LINE__, message); - -/** - * Asserts that two values are ==. - */ -#define assertSame(a, b) assertTrueWithSource(a == b, __FILE__, __LINE__, "Expected same value."); - -/** - * Asserts that two values are !=. - */ -#define assertNotSame(a, b) assertTrueWithSource(a != b, __FILE__, __LINE__,\ - "Expected different values"); - -/** - * Runs a test suite. - */ -void runTests(void); - -// Do not call these functions directly. Use macros above instead. -void addNamedTest(const char* name, void (*test)(void)); -void assertTrueWithSource(int value, const char* file, int line, char* message); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_TEST_H */ diff --git a/include/cutils/adb_networking.h b/include/cutils/adb_networking.h deleted file mode 100755 index 409d577ecd0a088ab708e457a8da62b1f50af97d..0000000000000000000000000000000000000000 --- a/include/cutils/adb_networking.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ADB_NETWORKING_H -#define _ADB_NETWORKING_H 1 -#include <netinet/in.h> -#include <arpa/inet.h> -#include <sys/socket.h> - -#ifdef __cplusplus -extern "C" { -#endif - -extern int adb_networking_connect_fd(int fd, struct sockaddr_in *p_address); -extern int adb_networking_gethostbyname(const char *name, struct in_addr *p_out_addr); - -#ifdef __cplusplus -} -#endif - -#endif /*_ADB_NETWORKING_H*/ - diff --git a/include/cutils/array.h b/include/cutils/array.h deleted file mode 100644 index c97ff34cba10e42f4870218a1916d753f9054983..0000000000000000000000000000000000000000 --- a/include/cutils/array.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * A pointer array which intelligently expands its capacity ad needed. - */ - -#ifndef __ARRAY_H -#define __ARRAY_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdlib.h> - -/** An array. */ -typedef struct Array Array; - -/** Constructs a new array. Returns NULL if we ran out of memory. */ -Array* arrayCreate(); - -/** Frees an array. Does not free elements themselves. */ -void arrayFree(Array* array); - -/** Adds a pointer. Returns 0 is successful, < 0 otherwise. */ -int arrayAdd(Array* array, void* pointer); - -/** Gets the pointer at the specified index. */ -void* arrayGet(Array* array, int index); - -/** Removes the pointer at the given index and returns it. */ -void* arrayRemove(Array* array, int index); - -/** Sets pointer at the given index. Returns old pointer. */ -void* arraySet(Array* array, int index, void* pointer); - -/** Sets the array size. Sets new pointers to NULL. Returns 0 if successful, < 0 otherwise . */ -int arraySetSize(Array* array, int size); - -/** Returns the size of the given array. */ -int arraySize(Array* array); - -/** - * Returns a pointer to a C-style array which will be valid until this array - * changes. - */ -const void** arrayUnwrap(Array* array); - -#ifdef __cplusplus -} -#endif - -#endif /* __ARRAY_H */ diff --git a/include/cutils/ashmem.h b/include/cutils/ashmem.h deleted file mode 100644 index fd71352eba11fbbd990155b76fe056afb321a84d..0000000000000000000000000000000000000000 --- a/include/cutils/ashmem.h +++ /dev/null @@ -1,42 +0,0 @@ -/* cutils/ashmem.h - ** - ** Copyright 2008 The Android Open Source Project - ** - ** This file is dual licensed. It may be redistributed and/or modified - ** under the terms of the Apache 2.0 License OR version 2 of the GNU - ** General Public License. - */ - -#ifndef _CUTILS_ASHMEM_H -#define _CUTILS_ASHMEM_H - -#ifdef __cplusplus -extern "C" { -#endif - -int ashmem_create_region(const char *name, size_t size); -int ashmem_set_prot_region(int fd, int prot); -int ashmem_pin_region(int fd, size_t offset, size_t len); -int ashmem_unpin_region(int fd, size_t offset, size_t len); - -#ifdef __cplusplus -} -#endif - -#ifndef __ASHMEMIOC /* in case someone included <linux/ashmem.h> too */ - -#define ASHMEM_NAME_LEN 256 - -#define ASHMEM_NAME_DEF "dev/ashmem" - -/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */ -#define ASHMEM_NOT_PURGED 0 -#define ASHMEM_WAS_PURGED 1 - -/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */ -#define ASHMEM_IS_UNPINNED 0 -#define ASHMEM_IS_PINNED 1 - -#endif /* ! __ASHMEMIOC */ - -#endif /* _CUTILS_ASHMEM_H */ diff --git a/include/cutils/atomic.h b/include/cutils/atomic.h deleted file mode 100644 index 5694d66ac6103d61fd7301f10670c3572b47be4d..0000000000000000000000000000000000000000 --- a/include/cutils/atomic.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_CUTILS_ATOMIC_H -#define ANDROID_CUTILS_ATOMIC_H - -#include <stdint.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * NOTE: memory shared between threads is synchronized by all atomic operations - * below, this means that no explicit memory barrier is required: all reads or - * writes issued before android_atomic_* operations are guaranteed to complete - * before the atomic operation takes place. - */ - -void android_atomic_write(int32_t value, volatile int32_t* addr); - -/* - * all these atomic operations return the previous value - */ - - -int32_t android_atomic_inc(volatile int32_t* addr); -int32_t android_atomic_dec(volatile int32_t* addr); - -int32_t android_atomic_add(int32_t value, volatile int32_t* addr); -int32_t android_atomic_and(int32_t value, volatile int32_t* addr); -int32_t android_atomic_or(int32_t value, volatile int32_t* addr); - -int32_t android_atomic_swap(int32_t value, volatile int32_t* addr); - -/* - * NOTE: Two "quasiatomic" operations on the exact same memory address - * are guaranteed to operate atomically with respect to each other, - * but no guarantees are made about quasiatomic operations mixed with - * non-quasiatomic operations on the same address, nor about - * quasiatomic operations that are performed on partially-overlapping - * memory. - */ - -int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr); -int64_t android_quasiatomic_read_64(volatile int64_t* addr); - -/* - * cmpxchg return a non zero value if the exchange was NOT performed, - * in other words if oldvalue != *addr - */ - -int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, - volatile int32_t* addr); - -int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, - volatile int64_t* addr); - - - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // ANDROID_CUTILS_ATOMIC_H diff --git a/include/cutils/config_utils.h b/include/cutils/config_utils.h deleted file mode 100644 index f3fb370a8a35fda7b5faa3969e74a483db89c990..0000000000000000000000000000000000000000 --- a/include/cutils/config_utils.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_CONFIG_UTILS_H -#define __CUTILS_CONFIG_UTILS_H - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct cnode cnode; - - -struct cnode -{ - cnode *next; - cnode *first_child; - cnode *last_child; - const char *name; - const char *value; -}; - -/* parse a text string into a config node tree */ -void config_load(cnode *root, char *data); - -/* parse a file into a config node tree */ -void config_load_file(cnode *root, const char *fn); - -/* create a single config node */ -cnode* config_node(const char *name, const char *value); - -/* locate a named child of a config node */ -cnode* config_find(cnode *root, const char *name); - -/* look up a child by name and return the boolean value */ -int config_bool(cnode *root, const char *name, int _default); - -/* look up a child by name and return the string value */ -const char* config_str(cnode *root, const char *name, const char *_default); - -/* add a named child to a config node (or modify it if it already exists) */ -void config_set(cnode *root, const char *name, const char *value); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/cutils/cpu_info.h b/include/cutils/cpu_info.h deleted file mode 100644 index 78c1884335ee58ecf1cc0517cbc9e5b75a5861a2..0000000000000000000000000000000000000000 --- a/include/cutils/cpu_info.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_CPU_INFO_H -#define __CUTILS_CPU_INFO_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* returns a string contiaining an ASCII representation of the CPU serial number, -** or NULL if cpu info not available. -** The string is a static variable, so don't call free() on it. -*/ -extern const char* get_cpu_serial_number(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_CPU_INFO_H */ diff --git a/include/cutils/dir_hash.h b/include/cutils/dir_hash.h deleted file mode 100644 index fbb4d02c8d939dc9bd1ecbe795822a5c289d23f3..0000000000000000000000000000000000000000 --- a/include/cutils/dir_hash.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -typedef enum { - SHA_1, -} HashAlgorithm; - -int get_file_hash(HashAlgorithm algorithm, const char *path, - char *output_string, size_t max_output_string); - -int get_recursive_hash_manifest(HashAlgorithm algorithm, - const char *directory_path, - char **output_string); diff --git a/include/cutils/event_tag_map.h b/include/cutils/event_tag_map.h deleted file mode 100644 index 1653c61e9a41947fdb37723b908f87ab18a6c8ad..0000000000000000000000000000000000000000 --- a/include/cutils/event_tag_map.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBS_CUTILS_EVENTTAGMAP_H -#define _LIBS_CUTILS_EVENTTAGMAP_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define EVENT_TAG_MAP_FILE "/system/etc/event-log-tags" - -struct EventTagMap; -typedef struct EventTagMap EventTagMap; - -/* - * Open the specified file as an event log tag map. - * - * Returns NULL on failure. - */ -EventTagMap* android_openEventTagMap(const char* fileName); - -/* - * Close the map. - */ -void android_closeEventTagMap(EventTagMap* map); - -/* - * Look up a tag by index. Returns the tag string, or NULL if not found. - */ -const char* android_lookupEventTag(const EventTagMap* map, int tag); - -#ifdef __cplusplus -} -#endif - -#endif /*_LIBS_CUTILS_EVENTTAGMAP_H*/ diff --git a/include/cutils/fdevent.h b/include/cutils/fdevent.h deleted file mode 100644 index 7a442d46c80deb27cd467a2822a16243eb3cdba0..0000000000000000000000000000000000000000 --- a/include/cutils/fdevent.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __FDEVENT_H -#define __FDEVENT_H - -/* events that may be observed */ -#define FDE_READ 0x0001 -#define FDE_WRITE 0x0002 -#define FDE_ERROR 0x0004 - -/* features that may be set (via the events set/add/del interface) */ -#define FDE_DONT_CLOSE 0x0080 - -typedef struct fdevent fdevent; - -typedef void (*fd_func)(int fd, unsigned events, void *userdata); - -/* Allocate and initialize a new fdevent object -*/ -fdevent *fdevent_create(int fd, fd_func func, void *arg); - -/* Uninitialize and deallocate an fdevent object that was -** created by fdevent_create() -*/ -void fdevent_destroy(fdevent *fde); - -/* Initialize an fdevent object that was externally allocated -*/ -void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg); - -/* Uninitialize an fdevent object that was initialized by -** fdevent_install() -*/ -void fdevent_remove(fdevent *item); - -/* Change which events should cause notifications -*/ -void fdevent_set(fdevent *fde, unsigned events); -void fdevent_add(fdevent *fde, unsigned events); -void fdevent_del(fdevent *fde, unsigned events); - -/* loop forever, handling events. -*/ -void fdevent_loop(); - -struct fdevent -{ - fdevent *next; - fdevent *prev; - - int fd; - unsigned short state; - unsigned short events; - - fd_func func; - void *arg; -}; - - -#endif diff --git a/include/cutils/hashmap.h b/include/cutils/hashmap.h deleted file mode 100644 index 5cb344c152beb3bf0e508eb092aff28b774379ae..0000000000000000000000000000000000000000 --- a/include/cutils/hashmap.h +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Hash map. - */ - -#ifndef __HASHMAP_H -#define __HASHMAP_H - -#include <stdbool.h> -#include <stdlib.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** A hash map. */ -typedef struct Hashmap Hashmap; - -/** - * Creates a new hash map. Returns NULL if memory allocation fails. - * - * @param initialCapacity number of expected entries - * @param hash function which hashes keys - * @param equals function which compares keys for equality - */ -Hashmap* hashmapCreate(size_t initialCapacity, - int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB)); - -/** - * Frees the hash map. Does not free the keys or values themselves. - */ -void hashmapFree(Hashmap* map); - -/** - * Hashes the memory pointed to by key with the given size. Useful for - * implementing hash functions. - */ -int hashmapHash(void* key, size_t keySize); - -/** - * Puts value for the given key in the map. Returns pre-existing value if - * any. - * - * If memory allocation fails, this function returns NULL, the map's size - * does not increase, and errno is set to ENOMEM. - */ -void* hashmapPut(Hashmap* map, void* key, void* value); - -/** - * Gets a value from the map. Returns NULL if no entry for the given key is - * found or if the value itself is NULL. - */ -void* hashmapGet(Hashmap* map, void* key); - -/** - * Returns true if the map contains an entry for the given key. - */ -bool hashmapContainsKey(Hashmap* map, void* key); - -/** - * Gets the value for a key. If a value is not found, this function gets a - * value and creates an entry using the given callback. - * - * If memory allocation fails, the callback is not called, this function - * returns NULL, and errno is set to ENOMEM. - */ -void* hashmapMemoize(Hashmap* map, void* key, - void* (*initialValue)(void* key, void* context), void* context); - -/** - * Removes an entry from the map. Returns the removed value or NULL if no - * entry was present. - */ -void* hashmapRemove(Hashmap* map, void* key); - -/** - * Gets the number of entries in this map. - */ -size_t hashmapSize(Hashmap* map); - -/** - * Invokes the given callback on each entry in the map. Stops iterating if - * the callback returns false. - */ -void hashmapForEach(Hashmap* map, - bool (*callback)(void* key, void* value, void* context), - void* context); - -/** - * Concurrency support. - */ - -/** - * Locks the hash map so only the current thread can access it. - */ -void hashmapLock(Hashmap* map); - -/** - * Unlocks the hash map so other threads can access it. - */ -void hashmapUnlock(Hashmap* map); - -/** - * Key utilities. - */ - -/** - * Hashes int keys. 'key' is a pointer to int. - */ -int hashmapIntHash(void* key); - -/** - * Compares two int keys for equality. - */ -bool hashmapIntEquals(void* keyA, void* keyB); - -/** - * For debugging. - */ - -/** - * Gets current capacity. - */ -size_t hashmapCurrentCapacity(Hashmap* map); - -/** - * Counts the number of entry collisions. - */ -size_t hashmapCountCollisions(Hashmap* map); - -#ifdef __cplusplus -} -#endif - -#endif /* __HASHMAP_H */ diff --git a/include/cutils/jstring.h b/include/cutils/jstring.h deleted file mode 100644 index ee0018fcc7a52b1cd2ec74e1104bad318cbd20d8..0000000000000000000000000000000000000000 --- a/include/cutils/jstring.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_STRING16_H -#define __CUTILS_STRING16_H - -#include <stdint.h> -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef uint16_t char16_t; - -extern char * strndup16to8 (const char16_t* s, size_t n); -extern size_t strnlen16to8 (const char16_t* s, size_t n); -extern char * strncpy16to8 (char *dest, const char16_t*s, size_t n); - -extern char16_t * strdup8to16 (const char* s, size_t *out_len); -extern size_t strlen8to16 (const char* utf8Str); -extern char16_t * strcpy8to16 (char16_t *dest, const char*s, size_t *out_len); -extern char16_t * strcpylen8to16 (char16_t *dest, const char*s, int length, - size_t *out_len); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_STRING16_H */ diff --git a/include/cutils/log.h b/include/cutils/log.h deleted file mode 100644 index ec3cac878b284558880f88c6cf80e7d596c36e3c..0000000000000000000000000000000000000000 --- a/include/cutils/log.h +++ /dev/null @@ -1,346 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// C/C++ logging functions. See the logging documentation for API details. -// -// We'd like these to be available from C code (in case we import some from -// somewhere), so this has a C interface. -// -// The output will be correct when the log file is shared between multiple -// threads and/or multiple processes so long as the operating system -// supports O_APPEND. These calls have mutex-protected data structures -// and so are NOT reentrant. Do not use LOG in a signal handler. -// -#ifndef _LIBS_CUTILS_LOG_H -#define _LIBS_CUTILS_LOG_H - -#include <stdio.h> -#include <time.h> -#include <sys/types.h> -#include <unistd.h> -#ifdef HAVE_PTHREADS -#include <pthread.h> -#endif -#include <stdarg.h> - -#include <cutils/uio.h> -#include <cutils/logd.h> - -#ifdef __cplusplus -extern "C" { -#endif - -// --------------------------------------------------------------------- - -/* - * Normally we strip LOGV (VERBOSE messages) from release builds. - * You can modify this (for example with "#define LOG_NDEBUG 0" - * at the top of your source file) to change that behavior. - */ -#ifndef LOG_NDEBUG -#ifdef NDEBUG -#define LOG_NDEBUG 1 -#else -#define LOG_NDEBUG 0 -#endif -#endif - -/* - * This is the local tag used for the following simplified - * logging macros. You can change this preprocessor definition - * before using the other macros to change the tag. - */ -#ifndef LOG_TAG -#define LOG_TAG NULL -#endif - -// --------------------------------------------------------------------- - -/* - * Simplified macro to send a verbose log message using the current LOG_TAG. - */ -#ifndef LOGV -#if LOG_NDEBUG -#define LOGV(...) ((void)0) -#else -#define LOGV(...) ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) -#endif -#endif - -#define CONDITION(cond) (__builtin_expect((cond)!=0, 0)) - -#ifndef LOGV_IF -#if LOG_NDEBUG -#define LOGV_IF(cond, ...) ((void)0) -#else -#define LOGV_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)LOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) -#endif -#endif - -/* - * Simplified macro to send a debug log message using the current LOG_TAG. - */ -#ifndef LOGD -#define LOGD(...) ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef LOGD_IF -#define LOGD_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)LOG(LOG_DEBUG, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) -#endif - -/* - * Simplified macro to send an info log message using the current LOG_TAG. - */ -#ifndef LOGI -#define LOGI(...) ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef LOGI_IF -#define LOGI_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)LOG(LOG_INFO, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) -#endif - -/* - * Simplified macro to send a warning log message using the current LOG_TAG. - */ -#ifndef LOGW -#define LOGW(...) ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef LOGW_IF -#define LOGW_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)LOG(LOG_WARN, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) -#endif - -/* - * Simplified macro to send an error log message using the current LOG_TAG. - */ -#ifndef LOGE -#define LOGE(...) ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) -#endif - -#ifndef LOGE_IF -#define LOGE_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)LOG(LOG_ERROR, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) -#endif - -// --------------------------------------------------------------------- - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * verbose priority. - */ -#ifndef IF_LOGV -#if LOG_NDEBUG -#define IF_LOGV() if (false) -#else -#define IF_LOGV() IF_LOG(LOG_VERBOSE, LOG_TAG) -#endif -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * debug priority. - */ -#ifndef IF_LOGD -#define IF_LOGD() IF_LOG(LOG_DEBUG, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * info priority. - */ -#ifndef IF_LOGI -#define IF_LOGI() IF_LOG(LOG_INFO, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * warn priority. - */ -#ifndef IF_LOGW -#define IF_LOGW() IF_LOG(LOG_WARN, LOG_TAG) -#endif - -/* - * Conditional based on whether the current LOG_TAG is enabled at - * error priority. - */ -#ifndef IF_LOGE -#define IF_LOGE() IF_LOG(LOG_ERROR, LOG_TAG) -#endif - -// --------------------------------------------------------------------- - -/* - * Log a fatal error. If the given condition fails, this stops program - * execution like a normal assertion, but also generating the given message. - * It is NOT stripped from release builds. Note that the condition test - * is -inverted- from the normal assert() semantics. - */ -#define LOG_ALWAYS_FATAL_IF(cond, ...) \ - ( (CONDITION(cond)) \ - ? ((void)android_printAssert(#cond, LOG_TAG, __VA_ARGS__)) \ - : (void)0 ) - -#define LOG_ALWAYS_FATAL(...) \ - ( ((void)android_printAssert(NULL, LOG_TAG, __VA_ARGS__)) ) - -/* - * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that - * are stripped out of release builds. - */ -#if LOG_NDEBUG - -#define LOG_FATAL_IF(cond, ...) ((void)0) -#define LOG_FATAL(...) ((void)0) - -#else - -#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, __VA_ARGS__) -#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__) - -#endif - -/* - * Assertion that generates a log message when the assertion fails. - * Stripped out of release builds. Uses the current LOG_TAG. - */ -#define LOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), __VA_ARGS__) -//#define LOG_ASSERT(cond) LOG_FATAL_IF(!(cond), "Assertion failed: " #cond) - -// --------------------------------------------------------------------- - -/* - * Basic log message macro. - * - * Example: - * LOG(LOG_WARN, NULL, "Failed with error %d", errno); - * - * The second argument may be NULL or "" to indicate the "global" tag. - */ -#ifndef LOG -#define LOG(priority, tag, ...) \ - LOG_PRI(ANDROID_##priority, tag, __VA_ARGS__) -#endif - -/* - * Log macro that allows you to specify a number for the priority. - */ -#ifndef LOG_PRI -#define LOG_PRI(priority, tag, ...) \ - android_printLog(priority, tag, __VA_ARGS__) -#endif - -/* - * Log macro that allows you to pass in a varargs ("args" is a va_list). - */ -#ifndef LOG_PRI_VA -#define LOG_PRI_VA(priority, tag, fmt, args) \ - android_vprintLog(priority, NULL, tag, fmt, args) -#endif - -/* - * Conditional given a desired logging priority and tag. - */ -#ifndef IF_LOG -#define IF_LOG(priority, tag) \ - if (android_testLog(ANDROID_##priority, tag)) -#endif - -// --------------------------------------------------------------------- - -/* - * Event logging. - */ - -/* - * Event log entry types. These must match up with the declarations in - * java/android/android/util/EventLog.java. - */ -typedef enum { - EVENT_TYPE_INT = 0, - EVENT_TYPE_LONG = 1, - EVENT_TYPE_STRING = 2, - EVENT_TYPE_LIST = 3, -} AndroidEventLogType; - - -#define LOG_EVENT_INT(_tag, _value) { \ - int intBuf = _value; \ - (void) android_btWriteLog(_tag, EVENT_TYPE_INT, &intBuf, \ - sizeof(intBuf)); \ - } -#define LOG_EVENT_LONG(_tag, _value) { \ - long long longBuf = _value; \ - (void) android_btWriteLog(_tag, EVENT_TYPE_LONG, &longBuf, \ - sizeof(longBuf)); \ - } -#define LOG_EVENT_STRING(_tag, _value) \ - ((void) 0) /* not implemented -- must combine len with string */ -/* TODO: something for LIST */ - -/* - * =========================================================================== - * - * The stuff in the rest of this file should not be used directly. - */ - -#define android_printLog(prio, tag, fmt...) \ - __android_log_print(prio, tag, fmt) - -#define android_vprintLog(prio, cond, tag, fmt...) \ - __android_log_vprint(prio, tag, fmt) - -#define android_printAssert(cond, tag, fmt...) \ - __android_log_assert(cond, tag, fmt) - -#define android_writeLog(prio, tag, text) \ - __android_log_write(prio, tag, text) - -#define android_bWriteLog(tag, payload, len) \ - __android_log_bwrite(tag, payload, len) -#define android_btWriteLog(tag, type, payload, len) \ - __android_log_btwrite(tag, type, payload, len) - -// TODO: remove these prototypes and their users -#define android_testLog(prio, tag) (1) -#define android_writevLog(vec,num) do{}while(0) -#define android_write1Log(str,len) do{}while (0) -#define android_setMinPriority(tag, prio) do{}while(0) -//#define android_logToCallback(func) do{}while(0) -#define android_logToFile(tag, file) (0) -#define android_logToFd(tag, fd) (0) - - -#ifdef __cplusplus -} -#endif - -#endif // _LIBS_CUTILS_LOG_H diff --git a/include/cutils/logd.h b/include/cutils/logd.h deleted file mode 100644 index a1cb012c7e55a5e1458c49e553f5f282240a2a8f..0000000000000000000000000000000000000000 --- a/include/cutils/logd.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ANDROID_CUTILS_LOGD_H -#define _ANDROID_CUTILS_LOGD_H - -#include <time.h> -#include <stdio.h> -#include <unistd.h> -#include <stdint.h> -#include <sys/types.h> -#ifdef HAVE_PTHREADS -#include <pthread.h> -#endif -#include <cutils/uio.h> -#include <stdarg.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Priority values, in ascending priority order. - */ -typedef enum android_LogPriority { - ANDROID_LOG_UNKNOWN = 0, - ANDROID_LOG_DEFAULT, /* only for SetMinPriority() */ - ANDROID_LOG_VERBOSE, - ANDROID_LOG_DEBUG, - ANDROID_LOG_INFO, - ANDROID_LOG_WARN, - ANDROID_LOG_ERROR, - ANDROID_LOG_FATAL, - ANDROID_LOG_SILENT, /* only for SetMinPriority(); must be last */ -} android_LogPriority; - -int __android_log_write(int prio, const char *tag, const char *text); - -int __android_log_vprint(int prio, const char *tag, - const char *fmt, va_list ap); - -int __android_log_bwrite(int32_t tag, const void *payload, size_t len); -int __android_log_btwrite(int32_t tag, char type, const void *payload, - size_t len); - -int __android_log_print(int prio, const char *tag, const char *fmt, ...) -#if defined(__GNUC__) - __attribute__ ((format(printf, 3, 4))) -#endif - ; - - -void __android_log_assert(const char *cond, const char *tag, - const char *fmt, ...) -#if defined(__GNUC__) - __attribute__ ((noreturn)) - __attribute__ ((format(printf, 3, 4))) -#endif - ; - -#ifdef __cplusplus -} -#endif - -#endif /* _LOGD_H */ diff --git a/include/cutils/logger.h b/include/cutils/logger.h deleted file mode 100644 index 3a08019a8866c7a4ee19821a05c9b61701b025f2..0000000000000000000000000000000000000000 --- a/include/cutils/logger.h +++ /dev/null @@ -1,46 +0,0 @@ -/* utils/logger.h -** -** Copyright 2007, The Android Open Source Project -** -** This file is dual licensed. It may be redistributed and/or modified -** under the terms of the Apache 2.0 License OR version 2 of the GNU -** General Public License. -*/ - -#ifndef _UTILS_LOGGER_H -#define _UTILS_LOGGER_H - -#include <stdint.h> - -struct logger_entry { - uint16_t len; /* length of the payload */ - uint16_t __pad; /* no matter what, we get 2 bytes of padding */ - int32_t pid; /* generating process's pid */ - int32_t tid; /* generating process's tid */ - int32_t sec; /* seconds since Epoch */ - int32_t nsec; /* nanoseconds */ - char msg[0]; /* the entry's payload */ -}; - -#define LOGGER_LOG_MAIN "log/main" -#define LOGGER_LOG_RADIO "log/radio" -#define LOGGER_LOG_EVENTS "log/events" - -#define LOGGER_ENTRY_MAX_LEN (4*1024) -#define LOGGER_ENTRY_MAX_PAYLOAD \ - (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry)) - -#ifdef HAVE_IOCTL - -#include <sys/ioctl.h> - -#define __LOGGERIO 0xAE - -#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */ -#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */ -#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */ -#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */ - -#endif // HAVE_IOCTL - -#endif /* _UTILS_LOGGER_H */ diff --git a/include/cutils/logprint.h b/include/cutils/logprint.h deleted file mode 100644 index d6ec480cf790add3137604e51e25d4ab38ed9c05..0000000000000000000000000000000000000000 --- a/include/cutils/logprint.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LOGPRINT_H -#define _LOGPRINT_H - -#include <cutils/log.h> -#include <cutils/logger.h> -#include <cutils/event_tag_map.h> -#include <pthread.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - FORMAT_OFF = 0, - FORMAT_BRIEF, - FORMAT_PROCESS, - FORMAT_TAG, - FORMAT_THREAD, - FORMAT_RAW, - FORMAT_TIME, - FORMAT_THREADTIME, - FORMAT_LONG, -} AndroidLogPrintFormat; - -typedef struct AndroidLogFormat_t AndroidLogFormat; - -typedef struct AndroidLogEntry_t { - time_t tv_sec; - long tv_nsec; - android_LogPriority priority; - pid_t pid; - pthread_t tid; - const char * tag; - size_t messageLen; - const char * message; -} AndroidLogEntry; - -AndroidLogFormat *android_log_format_new(); - -void android_log_format_free(AndroidLogFormat *p_format); - -void android_log_setPrintFormat(AndroidLogFormat *p_format, - AndroidLogPrintFormat format); - -/** - * Returns FORMAT_OFF on invalid string - */ -AndroidLogPrintFormat android_log_formatFromString(const char *s); - -/** - * filterExpression: a single filter expression - * eg "AT:d" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ - -int android_log_addFilterRule(AndroidLogFormat *p_format, - const char *filterExpression); - - -/** - * filterString: a whitespace-separated set of filter expressions - * eg "AT:d *:i" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ - -int android_log_addFilterString(AndroidLogFormat *p_format, - const char *filterString); - - -/** - * returns 1 if this log line should be printed based on its priority - * and tag, and 0 if it should not - */ -int android_log_shouldPrintLine ( - AndroidLogFormat *p_format, const char *tag, android_LogPriority pri); - - -/** - * Splits a wire-format buffer into an AndroidLogEntry - * entry allocated by caller. Pointers will point directly into buf - * - * Returns 0 on success and -1 on invalid wire format (entry will be - * in unspecified state) - */ -int android_log_processLogBuffer(struct logger_entry *buf, - AndroidLogEntry *entry); - -/** - * Like android_log_processLogBuffer, but for binary logs. - * - * If "map" is non-NULL, it will be used to convert the log tag number - * into a string. - */ -int android_log_processBinaryLogBuffer(struct logger_entry *buf, - AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf, - int messageBufLen); - - -/** - * Formats a log message into a buffer - * - * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer - * If return value != defaultBuffer, caller must call free() - * Returns NULL on malloc error - */ - -char *android_log_formatLogLine ( - AndroidLogFormat *p_format, - char *defaultBuffer, - size_t defaultBufferSize, - const AndroidLogEntry *p_line, - size_t *p_outLength); - - -/** - * Either print or do not print log line, based on filter - * - * Assumes single threaded execution - * - */ -int android_log_filterAndPrintLogLine( - AndroidLogFormat *p_format, - int fd, - const AndroidLogEntry *entry); - - -#ifdef __cplusplus -} -#endif - - -#endif /*_LOGPRINT_H*/ diff --git a/include/cutils/memory.h b/include/cutils/memory.h deleted file mode 100644 index e725cdd032229125227e235d057069b5425d8595..0000000000000000000000000000000000000000 --- a/include/cutils/memory.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_CUTILS_MEMORY_H -#define ANDROID_CUTILS_MEMORY_H - -#include <stdint.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* size is given in bytes and must be multiple of 2 */ -void android_memset16(uint16_t* dst, uint16_t value, size_t size); - -/* size is given in bytes and must be multiple of 4 */ -void android_memset32(uint32_t* dst, uint32_t value, size_t size); - -#if !HAVE_STRLCPY -/* Declaration of strlcpy() for platforms that don't already have it. */ -size_t strlcpy(char *dst, const char *src, size_t size); -#endif - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // ANDROID_CUTILS_MEMORY_H diff --git a/include/cutils/misc.h b/include/cutils/misc.h deleted file mode 100644 index 2c48dfa830a9c7eb333fb9db89d75751df0b347d..0000000000000000000000000000000000000000 --- a/include/cutils/misc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_MISC_H -#define __CUTILS_MISC_H - -#ifdef __cplusplus -extern "C" { -#endif - - /* Load an entire file into a malloc'd chunk of memory - * that is length_of_file + 1 (null terminator). If - * sz is non-zero, return the size of the file via sz. - * Returns 0 on failure. - */ -extern void *load_file(const char *fn, unsigned *sz); - - /* Connects your process to the system debugger daemon - * so that on a crash it may be logged or interactively - * debugged (depending on system settings). - */ -extern void debuggerd_connect(void); - - - /* This is the range of UIDs (and GIDs) that are reserved - * for assigning to applications. - */ -#define FIRST_APPLICATION_UID 10000 -#define LAST_APPLICATION_UID 99999 - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_MISC_H */ diff --git a/include/cutils/mq.h b/include/cutils/mq.h deleted file mode 100644 index b27456d4f26a8cc37a5ed1964b6f735a4b68a79c..0000000000000000000000000000000000000000 --- a/include/cutils/mq.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * IPC messaging library. - */ - -#ifndef __MQ_H -#define __MQ_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** A message. */ -typedef struct MqMessage MqMessage; - -/** A destination to which messages can be sent. */ -typedef struct MqDestination MqDestination; - -/* Array of bytes. */ -typedef struct MqBytes MqBytes; - -/** - * Hears messages. - * - * @param destination to which the message was sent - * @param message the message to hear - */ -typedef void MqMessageListener(MqDestination* destination, MqMessage* message); - -/** - * Hears a destination close. - * - * @param destination that closed - */ -typedef void MqCloseListener(MqDestination* destination); - -/** Message functions. */ - -/** - * Creates a new Message. - * - * @param header as defined by user - * @param body as defined by user - * @param replyTo destination to which replies should be sent, NULL if none - */ -MqMessage* mqCreateMessage(MqBytes header, MqBytes body, - MqDestination* replyTo); - -/** Sends a message to a destination. */ -void mqSendMessage(MqMessage* message, MqDestination* destination); - -/** Destination functions. */ - -/** - * Creates a new destination. Acquires a reference implicitly. - * - * @param messageListener function to call when a message is recieved - * @param closeListener function to call when the destination closes - * @param userData user-specific data to associate with the destination. - * Retrieve using mqGetDestinationUserData(). - */ -MqDestination* mqCreateDestination(MqMessageListener* messageListener, - MqCloseListener* closeListener, void* userData); - -/** - * Gets user data which was associated with the given destination at - * construction time. - * - * It is only valid to call this function in the same process that the - * given destination was created in. - * This function returns a null pointer if you call it on a destination - * created in a remote process. - */ -void* mqGetUserData(MqDestination* destination); - -/** - * Returns 1 if the destination was created in this process, or 0 if - * the destination was created in a different process, in which case you have - * a remote stub. - */ -int mqIsDestinationLocal(MqDestination* destination); - -/** - * Increments the destination's reference count. - */ -void mqKeepDestination(MqDesintation* destination); - -/** - * Decrements the destination's reference count. - */ -void mqFreeDestination(MqDestination* desintation); - -/** Registry API. */ - -/** - * Gets the destination bound to a name. - */ -MqDestination* mqGetDestination(char* name); - -/** - * Binds a destination to a name. - */ -void mqPutDestination(char* name, MqDestination* desintation); - -#ifdef __cplusplus -} -#endif - -#endif /* __MQ_H */ diff --git a/include/cutils/mspace.h b/include/cutils/mspace.h deleted file mode 100644 index 33410c105005092f861c12fa16546dbc577d60ff..0000000000000000000000000000000000000000 --- a/include/cutils/mspace.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* A wrapper file for dlmalloc.h that defines prototypes for the - * mspace_*() functions, which provide an interface for creating - * multiple heaps. - */ - -#ifndef MSPACE_H_ -#define MSPACE_H_ - -/* It's a pain getting the mallinfo stuff to work - * with Linux, OSX, and klibc, so just turn it off - * for now. - * TODO: make mallinfo work - */ -#define NO_MALLINFO 1 - -/* Allow setting the maximum heap footprint. - */ -#define USE_MAX_ALLOWED_FOOTPRINT 1 - -#define USE_CONTIGUOUS_MSPACES 1 -#if USE_CONTIGUOUS_MSPACES -#define HAVE_MMAP 0 -#define HAVE_MORECORE 1 -#define MORECORE_CONTIGUOUS 0 -#endif - -#define MSPACES 1 -#define ONLY_MSPACES 1 -#include "../../../../bionic/libc/bionic/dlmalloc.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - mspace_usable_size(void* p); - - Returns the number of bytes you can actually use in - an allocated chunk, which may be more than you requested (although - often not) due to alignment and minimum size constraints. - You can use this many bytes without worrying about - overwriting other allocated objects. This is not a particularly great - programming practice. mspace_usable_size can be more useful in - debugging and assertions, for example: - - p = mspace_malloc(msp, n); - assert(mspace_usable_size(msp, p) >= 256); -*/ -size_t mspace_usable_size(mspace, const void*); - -#if USE_CONTIGUOUS_MSPACES -/* - Similar to create_mspace(), but the underlying memory is - guaranteed to be contiguous. No more than max_capacity - bytes is ever allocated to the mspace. - */ -mspace create_contiguous_mspace(size_t starting_capacity, size_t max_capacity, - int locked); - -/* - Identical to create_contiguous_mspace, but labels the mapping 'mspace/name' - instead of 'mspace' -*/ -mspace create_contiguous_mspace_with_name(size_t starting_capacity, - size_t max_capacity, int locked, const char *name); - -size_t destroy_contiguous_mspace(mspace msp); -#endif - -/* - Call the handler for each block in the specified mspace. - chunkptr and chunklen refer to the heap-level chunk including - the chunk overhead, and userptr and userlen refer to the - user-usable part of the chunk. If the chunk is free, userptr - will be NULL and userlen will be 0. userlen is not guaranteed - to be the same value passed into malloc() for a given chunk; - it is >= the requested size. - */ -void mspace_walk_heap(mspace msp, - void(*handler)(const void *chunkptr, size_t chunklen, - const void *userptr, size_t userlen, void *arg), void *harg); - -/* - mspace_walk_free_pages(handler, harg) - - Calls the provided handler on each free region in the specified - mspace. The memory between start and end are guaranteed not to - contain any important data, so the handler is free to alter the - contents in any way. This can be used to advise the OS that large - free regions may be swapped out. - - The value in harg will be passed to each call of the handler. - */ -void mspace_walk_free_pages(mspace msp, - void(*handler)(void *start, void *end, void *arg), void *harg); - -#ifdef __cplusplus -}; /* end of extern "C" */ -#endif - -#endif /* MSPACE_H_ */ diff --git a/include/cutils/native_handle.h b/include/cutils/native_handle.h deleted file mode 100644 index 2b648935c5772cf523cefb9f04d90bd99dedda1e..0000000000000000000000000000000000000000 --- a/include/cutils/native_handle.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef NATIVE_HANDLE_H_ -#define NATIVE_HANDLE_H_ - -typedef struct -{ - int version; /* sizeof(native_handle) */ - int numFds; /* number of file-descriptors at &data[0] */ - int numInts; /* number of ints at &data[numFds] */ - int data[0]; /* numFds + numInts ints */ -} native_handle; - -#endif /* NATIVE_HANDLE_H_ */ diff --git a/include/cutils/process_name.h b/include/cutils/process_name.h deleted file mode 100644 index 1e72e5c3ad30870f033233602246ab35bf00a97e..0000000000000000000000000000000000000000 --- a/include/cutils/process_name.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Gives the current process a name. - */ - -#ifndef __PROCESS_NAME_H -#define __PROCESS_NAME_H - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * Sets the current process name. - * - * Warning: This leaks a string every time you call it. Use judiciously! - */ -void set_process_name(const char* process_name); - -/** Gets the current process name. */ -const char* get_process_name(void); - -#ifdef __cplusplus -} -#endif - -#endif /* __PROCESS_NAME_H */ diff --git a/include/cutils/properties.h b/include/cutils/properties.h deleted file mode 100644 index 25fd67ae0e49f4f0fb473f0278374410c58ccee3..0000000000000000000000000000000000000000 --- a/include/cutils/properties.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_PROPERTIES_H -#define __CUTILS_PROPERTIES_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* System properties are *small* name value pairs managed by the -** property service. If your data doesn't fit in the provided -** space it is not appropriate for a system property. -** -** WARNING: system/bionic/include/sys/system_properties.h also defines -** these, but with different names. (TODO: fix that) -*/ -#define PROPERTY_KEY_MAX 32 -#define PROPERTY_VALUE_MAX 92 - -/* property_get: returns the length of the value which will never be -** greater than PROPERTY_VALUE_MAX - 1 and will always be zero terminated. -** (the length does not include the terminating zero). -** -** If the property read fails or returns an empty value, the default -** value is used (if nonnull). -*/ -int property_get(const char *key, char *value, const char *default_value); - -/* property_set: returns 0 on success, < 0 on failure -*/ -int property_set(const char *key, const char *value); - -int property_list(void (*propfn)(const char *key, const char *value, void *cookie), void *cookie); - - -#ifdef HAVE_SYSTEM_PROPERTY_SERVER -/* - * We have an external property server instead of built-in libc support. - * Used by the simulator. - */ -#define SYSTEM_PROPERTY_PIPE_NAME "/tmp/android-sysprop" - -enum { - kSystemPropertyUnknown = 0, - kSystemPropertyGet, - kSystemPropertySet, - kSystemPropertyList -}; -#endif /*HAVE_SYSTEM_PROPERTY_SERVER*/ - - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/cutils/record_stream.h b/include/cutils/record_stream.h deleted file mode 100644 index bfac87a53cac9f4794ccf238a1322e6cca2950b6..0000000000000000000000000000000000000000 --- a/include/cutils/record_stream.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * A simple utility for reading fixed records out of a stream fd - */ - -#ifndef _CUTILS_RECORD_STREAM_H -#define _CUTILS_RECORD_STREAM_H - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct RecordStream RecordStream; - -extern RecordStream *record_stream_new(int fd, size_t maxRecordLen); -extern void record_stream_free(RecordStream *p_rs); - -extern int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, - size_t *p_outRecordLen); - -#ifdef __cplusplus -} -#endif - - -#endif /*_CUTILS_RECORD_STREAM_H*/ - diff --git a/include/cutils/selector.h b/include/cutils/selector.h deleted file mode 100644 index dfc2a9d3491506108fc4aa4f3f300f256240f1c1..0000000000000000000000000000000000000000 --- a/include/cutils/selector.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Framework for multiplexing I/O. A selector manages a set of file - * descriptors and calls out to user-provided callback functions to read and - * write data and handle errors. - */ - -#ifndef __SELECTOR_H -#define __SELECTOR_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdbool.h> - -/** - * Manages SelectableFds and invokes their callbacks at appropriate times. - */ -typedef struct Selector Selector; - -/** - * A selectable descriptor. Contains callbacks which the selector can invoke - * before calling select(), when the descriptor is readable or writable, and - * when the descriptor contains out-of-band data. Simply set a callback to - * NULL if you're not interested in that particular event. - * - * A selectable descriptor can indicate that it needs to be removed from the - * selector by setting the 'remove' flag. The selector will remove the - * descriptor at a later time and invoke the onRemove() callback. - * - * SelectableFd fields should only be modified from the selector loop. - */ -typedef struct SelectableFd SelectableFd; -struct SelectableFd { - - /** The file descriptor itself. */ - int fd; - - /** Pointer to user-specific data. Can be NULL. */ - void* data; - - /** - * Set this flag when you no longer wish to be selected. The selector - * will invoke onRemove() when the descriptor is actually removed. - */ - bool remove; - - /** - * Invoked by the selector before calling select. You can set up other - * callbacks from here as necessary. - */ - void (*beforeSelect)(SelectableFd* self); - - /** - * Invoked by the selector when the descriptor has data available. Set to - * NULL to indicate that you're not interested in reading. - */ - void (*onReadable)(SelectableFd* self); - - /** - * Invoked by the selector when the descriptor can accept data. Set to - * NULL to indicate that you're not interested in writing. - */ - void (*onWritable)(SelectableFd* self); - - /** - * Invoked by the selector when out-of-band (OOB) data is available. Set to - * NULL to indicate that you're not interested in OOB data. - */ - void (*onExcept)(SelectableFd* self); - - /** - * Invoked by the selector after the descriptor is removed from the - * selector but before the selector frees the SelectableFd memory. - */ - void (*onRemove)(SelectableFd* self); - - /** - * The selector which selected this fd. Set by the selector itself. - */ - Selector* selector; -}; - -/** - * Creates a new selector. - */ -Selector* selectorCreate(void); - -/** - * Creates a new selectable fd, adds it to the given selector and returns a - * pointer. Outside of 'selector' and 'fd', all fields are set to 0 or NULL - * by default. - * - * The selectable fd should only be modified from the selector loop thread. - */ -SelectableFd* selectorAdd(Selector* selector, int fd); - -/** - * Wakes up the selector even though no I/O events occurred. Use this - * to indicate that you're ready to write to a descriptor. - */ -void selectorWakeUp(Selector* selector); - -/** - * Loops continuously selecting file descriptors and firing events. - * Does not return. - */ -void selectorLoop(Selector* selector); - -#ifdef __cplusplus -} -#endif - -#endif /* __SELECTOR_H */ diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h deleted file mode 100644 index aa8682ede3b400f10ee4ccc43ef5ef4ef10eabda..0000000000000000000000000000000000000000 --- a/include/cutils/sockets.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_SOCKETS_H -#define __CUTILS_SOCKETS_H - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_WINSOCK -#include <winsock2.h> -typedef int socklen_t; -#elif HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#define ANDROID_SOCKET_ENV_PREFIX "ANDROID_SOCKET_" -#define ANDROID_SOCKET_DIR "/dev/socket" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * android_get_control_socket - simple helper function to get the file - * descriptor of our init-managed Unix domain socket. `name' is the name of the - * socket, as given in init.rc. Returns -1 on error. - * - * This is inline and not in libcutils proper because we want to use this in - * third-party daemons with minimal modification. - */ -static inline int android_get_control_socket(const char *name) -{ - char key[64] = ANDROID_SOCKET_ENV_PREFIX; - const char *val; - int fd; - - /* build our environment variable, counting cycles like a wolf ... */ -#if HAVE_STRLCPY - strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, - name, - sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); -#else /* for the host, which may lack the almightly strncpy ... */ - strncpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, - name, - sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); - key[sizeof(key)-1] = '\0'; -#endif - - val = getenv(key); - if (!val) - return -1; - - errno = 0; - fd = strtol(val, NULL, 10); - if (errno) - return -1; - - return fd; -} - -/* - * See also android.os.LocalSocketAddress.Namespace - */ -// Linux "abstract" (non-filesystem) namespace -#define ANDROID_SOCKET_NAMESPACE_ABSTRACT 0 -// Android "reserved" (/dev/socket) namespace -#define ANDROID_SOCKET_NAMESPACE_RESERVED 1 -// Normal filesystem namespace -#define ANDROID_SOCKET_NAMESPACE_FILESYSTEM 2 - -extern int socket_loopback_client(int port, int type); -extern int socket_network_client(const char *host, int port, int type); -extern int socket_loopback_server(int port, int type); -extern int socket_local_server(const char *name, int namespaceId, int type); -extern int socket_local_server_bind(int s, const char *name, int namespaceId); -extern int socket_local_client_connect(int fd, - const char *name, int namespaceId, int type); -extern int socket_local_client(const char *name, int namespaceId, int type); -extern int socket_inaddr_any_server(int port, int type); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_SOCKETS_H */ diff --git a/include/cutils/threads.h b/include/cutils/threads.h deleted file mode 100644 index acf8f4843d92fc7a3a82c7601781361061a21ffa..0000000000000000000000000000000000000000 --- a/include/cutils/threads.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LIBS_CUTILS_THREADS_H -#define _LIBS_CUTILS_THREADS_H - -#ifdef __cplusplus -extern "C" { -#endif - -/***********************************************************************/ -/***********************************************************************/ -/***** *****/ -/***** local thread storage *****/ -/***** *****/ -/***********************************************************************/ -/***********************************************************************/ - -#ifdef HAVE_PTHREADS - -#include <pthread.h> - -typedef struct { - pthread_mutex_t lock; - int has_tls; - pthread_key_t tls; - -} thread_store_t; - -#define THREAD_STORE_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0, 0 } - -#elif defined HAVE_WIN32_THREADS - -#include <windows.h> - -typedef struct { - int lock_init; - int has_tls; - DWORD tls; - CRITICAL_SECTION lock; - -} thread_store_t; - -#define THREAD_STORE_INITIALIZER { 0, 0, 0, {0, 0, 0, 0, 0, 0} } - -#else -# error "no thread_store_t implementation for your platform !!" -#endif - -typedef void (*thread_store_destruct_t)(void* value); - -extern void* thread_store_get(thread_store_t* store); - -extern void thread_store_set(thread_store_t* store, - void* value, - thread_store_destruct_t destroy); - -/***********************************************************************/ -/***********************************************************************/ -/***** *****/ -/***** mutexes *****/ -/***** *****/ -/***********************************************************************/ -/***********************************************************************/ - -#ifdef HAVE_PTHREADS - -typedef pthread_mutex_t mutex_t; - -#define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER - -static __inline__ void mutex_lock(mutex_t* lock) -{ - pthread_mutex_lock(lock); -} -static __inline__ void mutex_unlock(mutex_t* lock) -{ - pthread_mutex_unlock(lock); -} -static __inline__ int mutex_init(mutex_t* lock) -{ - return pthread_mutex_init(lock, NULL); -} -static __inline__ void mutex_destroy(mutex_t* lock) -{ - pthread_mutex_destroy(lock); -} -#endif - -#ifdef HAVE_WIN32_THREADS -typedef struct { - int init; - CRITICAL_SECTION lock[1]; -} mutex_t; - -#define MUTEX_INITIALIZER { 0, {{ NULL, 0, 0, NULL, NULL, 0 }} } - -static __inline__ void mutex_lock(mutex_t* lock) -{ - if (!lock->init) { - lock->init = 1; - InitializeCriticalSection( lock->lock ); - lock->init = 2; - } else while (lock->init != 2) - Sleep(10); - - EnterCriticalSection(lock->lock); -} - -static __inline__ void mutex_unlock(mutex_t* lock) -{ - LeaveCriticalSection(lock->lock); -} -static __inline__ int mutex_init(mutex_t* lock) -{ - InitializeCriticalSection(lock->lock); - lock->init = 2; - return 0; -} -static __inline__ void mutex_destroy(mutex_t* lock) -{ - if (lock->init) { - lock->init = 0; - DeleteCriticalSection(lock->lock); - } -} -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* _LIBS_CUTILS_THREADS_H */ diff --git a/include/cutils/tztime.h b/include/cutils/tztime.h deleted file mode 100644 index 9b3ece84c2100675e9d5895f8a6e27ec0a64dd74..0000000000000000000000000000000000000000 --- a/include/cutils/tztime.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _CUTILS_TZTIME_H -#define _CUTILS_TZTIME_H - -#ifdef __cplusplus -extern "C" { -#endif - -time_t mktime_tz(struct tm * const tmp, char const * tz); -void localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz); - -struct strftime_locale { - const char *mon[12]; /* short names */ - const char *month[12]; /* long names */ - const char *wday[7]; /* short names */ - const char *weekday[7]; /* long names */ - const char *X_fmt; - const char *x_fmt; - const char *c_fmt; - const char *am; - const char *pm; - const char *date_fmt; -}; - -size_t strftime_tz(char *s, size_t max, const char *format, const struct tm *tm, const struct strftime_locale *locale); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_TZTIME_H */ - diff --git a/include/cutils/uio.h b/include/cutils/uio.h deleted file mode 100644 index 01a74d26f334c0cacaeea03a646ee627a09fbe7a..0000000000000000000000000000000000000000 --- a/include/cutils/uio.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// -// implementation of sys/uio.h for platforms that don't have it (Win32) -// -#ifndef _LIBS_CUTILS_UIO_H -#define _LIBS_CUTILS_UIO_H - -#ifdef HAVE_SYS_UIO_H -#include <sys/uio.h> -#else - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stddef.h> - -struct iovec { - const void* iov_base; - size_t iov_len; -}; - -extern int readv( int fd, struct iovec* vecs, int count ); -extern int writev( int fd, const struct iovec* vecs, int count ); - -#ifdef __cplusplus -} -#endif - -#endif /* !HAVE_SYS_UIO_H */ - -#endif /* _LIBS_UTILS_UIO_H */ - diff --git a/include/cutils/zygote.h b/include/cutils/zygote.h deleted file mode 100644 index 22721a6bdc634b951dce5bbefc2039d3ac19e407..0000000000000000000000000000000000000000 --- a/include/cutils/zygote.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __CUTILS_ZYGOTE_H -#define __CUTILS_ZYGOTE_H - -#ifdef __cplusplus -extern "C" { -#endif - -int zygote_run_oneshot(int sendStdio, int argc, const char **argv); -int zygote_run(int argc, const char **argv); -int zygote_run_wait(int argc, const char **argv, void (*post_run_func)(int)); - -#ifdef __cplusplus -} -#endif - -#endif /* __CUTILS_ZYGOTE_H */ diff --git a/include/mincrypt/rsa.h b/include/mincrypt/rsa.h deleted file mode 100644 index 7d7d57158d2f40a8a654079a391f8d01f13b715f..0000000000000000000000000000000000000000 --- a/include/mincrypt/rsa.h +++ /dev/null @@ -1,56 +0,0 @@ -/* rsa.h -** -** Copyright 2008, The Android Open Source Project -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * 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. -** * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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. -*/ - -#ifndef _EMBEDDED_RSA_H_ -#define _EMBEDDED_RSA_H_ - -#include <inttypes.h> - -#ifdef __cplusplus -extern "C" { -#endif - -#define RSANUMBYTES 256 /* 2048 bit key length */ -#define RSANUMWORDS (RSANUMBYTES / sizeof(uint32_t)) - -typedef struct RSAPublicKey { - int len; /* Length of n[] in number of uint32_t */ - uint32_t n0inv; /* -1 / n[0] mod 2^32 */ - uint32_t n[RSANUMWORDS]; /* modulus as little endian array */ - uint32_t rr[RSANUMWORDS]; /* R^2 as little endian array */ -} RSAPublicKey; - -int RSA_verify(const RSAPublicKey *key, - const uint8_t* signature, - const int len, - const uint8_t* sha); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/mincrypt/sha.h b/include/mincrypt/sha.h deleted file mode 100644 index c52346066bb0fe31d2fec88da1d14511b28b917b..0000000000000000000000000000000000000000 --- a/include/mincrypt/sha.h +++ /dev/null @@ -1,56 +0,0 @@ -/* sha.h -** -** Copyright 2008, The Android Open Source Project -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * 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. -** * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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. -*/ - -#ifndef _EMBEDDED_SHA_H_ -#define _EMBEDDED_SHA_H_ - -#include <inttypes.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct SHA_CTX { - uint64_t count; - uint8_t buf[64]; - uint32_t state[5]; -} SHA_CTX; - -void SHA_init(SHA_CTX *ctx); -void SHA_update(SHA_CTX *ctx, const void* data, int len); -const uint8_t* SHA_final(SHA_CTX *ctx); - -/* Convenience method. Returns digest parameter value. */ -const uint8_t* SHA(const void *data, int len, uint8_t *digest); - -#define SHA_DIGEST_SIZE 20 - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/include/pixelflinger/format.h b/include/pixelflinger/format.h deleted file mode 100644 index 6b2050c447af132ef180118da6c7abc02e3d1edd..0000000000000000000000000000000000000000 --- a/include/pixelflinger/format.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_PIXELFLINGER_FORMAT_H -#define ANDROID_PIXELFLINGER_FORMAT_H - -#include <stdint.h> -#include <sys/types.h> - -enum GGLPixelFormat { - // these constants need to match those - // in graphics/PixelFormat.java, ui/PixelFormat.h, BlitHardware.h - GGL_PIXEL_FORMAT_UNKNOWN = 0, - GGL_PIXEL_FORMAT_NONE = 0, - - GGL_PIXEL_FORMAT_RGBA_8888 = 1, // 4x8-bit ARGB - GGL_PIXEL_FORMAT_RGBX_8888 = 2, // 3x8-bit RGB stored in 32-bit chunks - GGL_PIXEL_FORMAT_RGB_888 = 3, // 3x8-bit RGB - GGL_PIXEL_FORMAT_RGB_565 = 4, // 16-bit RGB - GGL_PIXEL_FORMAT_BGRA_8888 = 5, // 4x8-bit BGRA - GGL_PIXEL_FORMAT_RGBA_5551 = 6, // 16-bit RGBA - GGL_PIXEL_FORMAT_RGBA_4444 = 7, // 16-bit RGBA - - GGL_PIXEL_FORMAT_A_8 = 8, // 8-bit A - GGL_PIXEL_FORMAT_L_8 = 9, // 8-bit L (R=G=B = L) - GGL_PIXEL_FORMAT_LA_88 = 0xA, // 16-bit LA - GGL_PIXEL_FORMAT_RGB_332 = 0xB, // 8-bit RGB (non paletted) - - // YCbCr formats (SP=semi-planar, P=planar) - GGL_PIXEL_FORMAT_YCbCr_422_SP= 0x10, - GGL_PIXEL_FORMAT_YCbCr_420_SP= 0x11, - GGL_PIXEL_FORMAT_YCbCr_422_P = 0x12, - GGL_PIXEL_FORMAT_YCbCr_420_P = 0x13, - GGL_PIXEL_FORMAT_YCbCr_422_I = 0x14, - GGL_PIXEL_FORMAT_YCbCr_420_I = 0x15, - - // reserved/special formats - GGL_PIXEL_FORMAT_Z_16 = 0x18, - GGL_PIXEL_FORMAT_S_8 = 0x19, - GGL_PIXEL_FORMAT_SZ_24 = 0x1A, - GGL_PIXEL_FORMAT_SZ_8 = 0x1B, -}; - -enum GGLFormatComponents { - GGL_STENCIL_INDEX = 0x1901, - GGL_DEPTH_COMPONENT = 0x1902, - GGL_ALPHA = 0x1906, - GGL_RGB = 0x1907, - GGL_RGBA = 0x1908, - GGL_LUMINANCE = 0x1909, - GGL_LUMINANCE_ALPHA = 0x190A, - GGL_Y_CB_CR_SP = 0x8000, - GGL_Y_CB_CR = GGL_Y_CB_CR_SP, - GGL_Y_CB_CR_P = 0x8001, - GGL_Y_CB_CR_I = 0x8002, -}; - -enum GGLFormatComponentIndex { - GGL_INDEX_ALPHA = 0, - GGL_INDEX_RED = 1, - GGL_INDEX_GREEN = 2, - GGL_INDEX_BLUE = 3, - GGL_INDEX_STENCIL = 0, - GGL_INDEX_DEPTH = 1, - GGL_INDEX_Y = 0, - GGL_INDEX_CB = 1, - GGL_INDEX_CR = 2, -}; - -typedef struct { -#ifdef __cplusplus - enum { - ALPHA = GGL_INDEX_ALPHA, - RED = GGL_INDEX_RED, - GREEN = GGL_INDEX_GREEN, - BLUE = GGL_INDEX_BLUE, - STENCIL = GGL_INDEX_STENCIL, - DEPTH = GGL_INDEX_DEPTH, - LUMA = GGL_INDEX_Y, - CHROMAB = GGL_INDEX_CB, - CHROMAR = GGL_INDEX_CR, - }; - inline uint32_t mask(int i) const { - return ((1<<(c[i].h-c[i].l))-1)<<c[i].l; - } - inline uint32_t bits(int i) const { - return c[i].h - c[i].l; - } -#endif - uint8_t size; // bytes per pixel - uint8_t bitsPerPixel; - union { - struct { - uint8_t ah; // alpha high bit position + 1 - uint8_t al; // alpha low bit position - uint8_t rh; // red high bit position + 1 - uint8_t rl; // red low bit position - uint8_t gh; // green high bit position + 1 - uint8_t gl; // green low bit position - uint8_t bh; // blue high bit position + 1 - uint8_t bl; // blue low bit position - }; - struct { - uint8_t h; - uint8_t l; - } __attribute__((__packed__)) c[4]; - } __attribute__((__packed__)); - uint16_t components; // GGLFormatComponents -} GGLFormat; - - -#ifdef __cplusplus -extern "C" const GGLFormat* gglGetPixelFormatTable(size_t* numEntries = 0); -#else -const GGLFormat* gglGetPixelFormatTable(size_t* numEntries); -#endif - - -// ---------------------------------------------------------------------------- - -#endif // ANDROID_PIXELFLINGER_FORMAT_H diff --git a/include/pixelflinger/pixelflinger.h b/include/pixelflinger/pixelflinger.h deleted file mode 100644 index dca0b907394b781a526522b1d67e7049189b2a7f..0000000000000000000000000000000000000000 --- a/include/pixelflinger/pixelflinger.h +++ /dev/null @@ -1,330 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_PIXELFLINGER_H -#define ANDROID_PIXELFLINGER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <pixelflinger/format.h> - -// GGL types - -typedef int8_t GGLbyte; // b -typedef int16_t GGLshort; // s -typedef int32_t GGLint; // i -typedef ssize_t GGLsizei; // i -typedef int32_t GGLfixed; // x -typedef int32_t GGLclampx; // x -typedef float GGLfloat; // f -typedef float GGLclampf; // f -typedef double GGLdouble; // d -typedef double GGLclampd; // d -typedef uint8_t GGLubyte; // ub -typedef uint8_t GGLboolean; // ub -typedef uint16_t GGLushort; // us -typedef uint32_t GGLuint; // ui -typedef unsigned int GGLenum; // ui -typedef unsigned int GGLbitfield; // ui -typedef void GGLvoid; -typedef int32_t GGLfixed32; -typedef int32_t GGLcolor; -typedef int32_t GGLcoord; - -// ---------------------------------------------------------------------------- - -#define GGL_MAX_VIEWPORT_DIMS 4096 -#define GGL_MAX_TEXTURE_SIZE 4096 -#define GGL_MAX_ALIASED_POINT_SIZE 0x7FFFFFF -#define GGL_MAX_SMOOTH_POINT_SIZE 2048 -#define GGL_MAX_SMOOTH_LINE_WIDTH 2048 - -// ---------------------------------------------------------------------------- - -// All these names are compatible with their OpenGL equivalents -// some of them are listed only for completeness -enum GGLNames { - GGL_FALSE = 0, - GGL_TRUE = 1, - - // enable/disable - GGL_SCISSOR_TEST = 0x0C11, - GGL_TEXTURE_2D = 0x0DE1, - GGL_ALPHA_TEST = 0x0BC0, - GGL_BLEND = 0x0BE2, - GGL_COLOR_LOGIC_OP = 0x0BF2, - GGL_DITHER = 0x0BD0, - GGL_STENCIL_TEST = 0x0B90, - GGL_DEPTH_TEST = 0x0B71, - GGL_AA = 0x80000001, - GGL_W_LERP = 0x80000004, - GGL_POINT_SMOOTH_NICE = 0x80000005, - - // buffers, pixel drawing/reading - GGL_COLOR = 0x1800, - - // fog - GGL_FOG = 0x0B60, - - // shade model - GGL_FLAT = 0x1D00, - GGL_SMOOTH = 0x1D01, - - // Texture parameter name - GGL_TEXTURE_MIN_FILTER = 0x2801, - GGL_TEXTURE_MAG_FILTER = 0x2800, - GGL_TEXTURE_WRAP_S = 0x2802, - GGL_TEXTURE_WRAP_T = 0x2803, - GGL_TEXTURE_WRAP_R = 0x2804, - - // Texture Filter - GGL_NEAREST = 0x2600, - GGL_LINEAR = 0x2601, - GGL_NEAREST_MIPMAP_NEAREST = 0x2700, - GGL_LINEAR_MIPMAP_NEAREST = 0x2701, - GGL_NEAREST_MIPMAP_LINEAR = 0x2702, - GGL_LINEAR_MIPMAP_LINEAR = 0x2703, - - // Texture Wrap Mode - GGL_CLAMP = 0x2900, - GGL_REPEAT = 0x2901, - GGL_CLAMP_TO_EDGE = 0x812F, - - // Texture Env Mode - GGL_REPLACE = 0x1E01, - GGL_MODULATE = 0x2100, - GGL_DECAL = 0x2101, - GGL_ADD = 0x0104, - - // Texture Env Parameter - GGL_TEXTURE_ENV_MODE = 0x2200, - GGL_TEXTURE_ENV_COLOR = 0x2201, - - // Texture Env Target - GGL_TEXTURE_ENV = 0x2300, - - // Texture coord generation - GGL_TEXTURE_GEN_MODE = 0x2500, - GGL_S = 0x2000, - GGL_T = 0x2001, - GGL_R = 0x2002, - GGL_Q = 0x2003, - GGL_ONE_TO_ONE = 0x80000002, - GGL_AUTOMATIC = 0x80000003, - - // AlphaFunction - GGL_NEVER = 0x0200, - GGL_LESS = 0x0201, - GGL_EQUAL = 0x0202, - GGL_LEQUAL = 0x0203, - GGL_GREATER = 0x0204, - GGL_NOTEQUAL = 0x0205, - GGL_GEQUAL = 0x0206, - GGL_ALWAYS = 0x0207, - - // LogicOp - GGL_CLEAR = 0x1500, // 0 - GGL_AND = 0x1501, // s & d - GGL_AND_REVERSE = 0x1502, // s & ~d - GGL_COPY = 0x1503, // s - GGL_AND_INVERTED = 0x1504, // ~s & d - GGL_NOOP = 0x1505, // d - GGL_XOR = 0x1506, // s ^ d - GGL_OR = 0x1507, // s | d - GGL_NOR = 0x1508, // ~(s | d) - GGL_EQUIV = 0x1509, // ~(s ^ d) - GGL_INVERT = 0x150A, // ~d - GGL_OR_REVERSE = 0x150B, // s | ~d - GGL_COPY_INVERTED = 0x150C, // ~s - GGL_OR_INVERTED = 0x150D, // ~s | d - GGL_NAND = 0x150E, // ~(s & d) - GGL_SET = 0x150F, // 1 - - // blending equation & function - GGL_ZERO = 0, // SD - GGL_ONE = 1, // SD - GGL_SRC_COLOR = 0x0300, // D - GGL_ONE_MINUS_SRC_COLOR = 0x0301, // D - GGL_SRC_ALPHA = 0x0302, // SD - GGL_ONE_MINUS_SRC_ALPHA = 0x0303, // SD - GGL_DST_ALPHA = 0x0304, // SD - GGL_ONE_MINUS_DST_ALPHA = 0x0305, // SD - GGL_DST_COLOR = 0x0306, // S - GGL_ONE_MINUS_DST_COLOR = 0x0307, // S - GGL_SRC_ALPHA_SATURATE = 0x0308, // S - - // clear bits - GGL_DEPTH_BUFFER_BIT = 0x00000100, - GGL_STENCIL_BUFFER_BIT = 0x00000400, - GGL_COLOR_BUFFER_BIT = 0x00004000, - - // errors - GGL_NO_ERROR = 0, - GGL_INVALID_ENUM = 0x0500, - GGL_INVALID_VALUE = 0x0501, - GGL_INVALID_OPERATION = 0x0502, - GGL_STACK_OVERFLOW = 0x0503, - GGL_STACK_UNDERFLOW = 0x0504, - GGL_OUT_OF_MEMORY = 0x0505 -}; - -// ---------------------------------------------------------------------------- - -typedef struct { - GGLsizei version; // always set to sizeof(GGLSurface) - GGLuint width; // width in pixels - GGLuint height; // height in pixels - GGLint stride; // stride in pixels - GGLubyte* data; // pointer to the bits - GGLubyte format; // pixel format - GGLubyte rfu[3]; // must be zero - // these values are dependent on the used format - union { - GGLint compressedFormat; - GGLint vstride; - }; - void* reserved; -} GGLSurface; - - -typedef struct { - // immediate rendering - void (*pointx)(void *con, const GGLcoord* v, GGLcoord r); - void (*linex)(void *con, - const GGLcoord* v0, const GGLcoord* v1, GGLcoord width); - void (*recti)(void* c, GGLint l, GGLint t, GGLint r, GGLint b); - void (*trianglex)(void* c, - GGLcoord const* v0, GGLcoord const* v1, GGLcoord const* v2); - - // scissor - void (*scissor)(void* c, GGLint x, GGLint y, GGLsizei width, GGLsizei height); - - // Set the textures and color buffers - void (*activeTexture)(void* c, GGLuint tmu); - void (*bindTexture)(void* c, const GGLSurface* surface); - void (*colorBuffer)(void* c, const GGLSurface* surface); - void (*readBuffer)(void* c, const GGLSurface* surface); - void (*depthBuffer)(void* c, const GGLSurface* surface); - void (*bindTextureLod)(void* c, GGLuint tmu, const GGLSurface* surface); - - // enable/disable features - void (*enable)(void* c, GGLenum name); - void (*disable)(void* c, GGLenum name); - void (*enableDisable)(void* c, GGLenum name, GGLboolean en); - - // specify the fragment's color - void (*shadeModel)(void* c, GGLenum mode); - void (*color4xv)(void* c, const GGLclampx* color); - // specify color iterators (16.16) - void (*colorGrad12xv)(void* c, const GGLcolor* grad); - - // specify Z coordinate iterators (0.32) - void (*zGrad3xv)(void* c, const GGLfixed32* grad); - - // specify W coordinate iterators (16.16) - void (*wGrad3xv)(void* c, const GGLfixed* grad); - - // specify fog iterator & color (16.16) - void (*fogGrad3xv)(void* c, const GGLfixed* grad); - void (*fogColor3xv)(void* c, const GGLclampx* color); - - // specify blending parameters - void (*blendFunc)(void* c, GGLenum src, GGLenum dst); - void (*blendFuncSeparate)(void* c, GGLenum src, GGLenum dst, - GGLenum srcAlpha, GGLenum dstAplha); - - // texture environnement (REPLACE / MODULATE / DECAL / BLEND) - void (*texEnvi)(void* c, GGLenum target, - GGLenum pname, - GGLint param); - - void (*texEnvxv)(void* c, GGLenum target, - GGLenum pname, const GGLfixed* params); - - // texture parameters (Wrapping, filter) - void (*texParameteri)(void* c, GGLenum target, - GGLenum pname, - GGLint param); - - // texture iterators (16.16) - void (*texCoord2i)(void* c, GGLint s, GGLint t); - void (*texCoord2x)(void* c, GGLfixed s, GGLfixed t); - - // s, dsdx, dsdy, scale, t, dtdx, dtdy, tscale - // This api uses block floating-point for S and T texture coordinates. - // All values are given in 16.16, scaled by 'scale'. In other words, - // set scale to 0, for 16.16 values. - void (*texCoordGradScale8xv)(void* c, GGLint tmu, const int32_t* grad8); - - void (*texGeni)(void* c, GGLenum coord, GGLenum pname, GGLint param); - - // masking - void (*colorMask)(void* c, GGLboolean red, - GGLboolean green, - GGLboolean blue, - GGLboolean alpha); - - void (*depthMask)(void* c, GGLboolean flag); - - void (*stencilMask)(void* c, GGLuint mask); - - // alpha func - void (*alphaFuncx)(void* c, GGLenum func, GGLclampx ref); - - // depth func - void (*depthFunc)(void* c, GGLenum func); - - // logic op - void (*logicOp)(void* c, GGLenum opcode); - - // clear - void (*clear)(void* c, GGLbitfield mask); - void (*clearColorx)(void* c, - GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a); - void (*clearDepthx)(void* c, GGLclampx depth); - void (*clearStencil)(void* c, GGLint s); - - // framebuffer operations - void (*copyPixels)(void* c, GGLint x, GGLint y, - GGLsizei width, GGLsizei height, GGLenum type); - void (*rasterPos2x)(void* c, GGLfixed x, GGLfixed y); - void (*rasterPos2i)(void* c, GGLint x, GGLint y); -} GGLContext; - -// ---------------------------------------------------------------------------- - -#ifdef __cplusplus -extern "C" { -#endif - -// construct / destroy the context -ssize_t gglInit(GGLContext** context); -ssize_t gglUninit(GGLContext* context); - -GGLint gglBitBlti( - GGLContext* c, - int tmu, - GGLint crop[4], - GGLint where[4]); - -#ifdef __cplusplus -}; -#endif - -// ---------------------------------------------------------------------------- - -#endif // ANDROID_PIXELFLINGER_H diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h deleted file mode 100644 index c8551872adf4a12912c011390b71acce9fd063d8..0000000000000000000000000000000000000000 --- a/include/private/android_filesystem_config.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* This file is used to define the properties of the filesystem -** images generated by build tools (mkbootfs and mkyaffs2image) and -** by the device side of adb. -*/ - -#ifndef _ANDROID_FILESYSTEM_CONFIG_H_ -#define _ANDROID_FILESYSTEM_CONFIG_H_ - -#include <string.h> -#include <sys/stat.h> -#include <sys/types.h> - -/* This is the master Users and Groups config for the platform. -** DO NOT EVER RENUMBER. -*/ - -#define AID_ROOT 0 /* traditional unix root user */ - -#define AID_SYSTEM 1000 /* system server */ - -#define AID_RADIO 1001 /* telephony subsystem, RIL */ -#define AID_BLUETOOTH 1002 /* bluetooth subsystem */ -#define AID_GRAPHICS 1003 /* graphics devices */ -#define AID_INPUT 1004 /* input devices */ -#define AID_AUDIO 1005 /* audio devices */ -#define AID_CAMERA 1006 /* camera devices */ -#define AID_LOG 1007 /* log devices */ -#define AID_COMPASS 1008 /* compass device */ -#define AID_MOUNT 1009 /* mountd socket */ -#define AID_WIFI 1010 /* wifi subsystem */ -#define AID_ADB 1011 /* android debug bridge (adbd) */ -#define AID_INSTALL 1012 /* group for installing packages */ -#define AID_MEDIA 1013 /* mediaserver process */ -#define AID_DHCP 1014 /* dhcp client */ - -#define AID_SHELL 2000 /* adb and debug shell user */ -#define AID_CACHE 2001 /* cache access */ -#define AID_DIAG 2002 /* access to diagnostic resources */ - -/* The 3000 series are intended for use as supplemental group id's only. - * They indicate special Android capabilities that the kernel is aware of. */ -#define AID_NET_BT_ADMIN 3001 /* bluetooth: create any socket */ -#define AID_NET_BT 3002 /* bluetooth: create sco, rfcomm or l2cap sockets */ -#define AID_INET 3003 /* can create AF_INET and AF_INET6 sockets */ -#define AID_NET_RAW 3004 /* can create raw INET sockets */ - -#define AID_MISC 9998 /* access to misc storage */ -#define AID_NOBODY 9999 - -#define AID_APP 10000 /* first app user */ - -#if !defined(EXCLUDE_FS_CONFIG_STRUCTURES) -struct android_id_info { - const char *name; - unsigned aid; -}; - -static struct android_id_info android_ids[] = { - { "root", AID_ROOT, }, - { "system", AID_SYSTEM, }, - { "radio", AID_RADIO, }, - { "bluetooth", AID_BLUETOOTH, }, - { "graphics", AID_GRAPHICS, }, - { "input", AID_INPUT, }, - { "audio", AID_AUDIO, }, - { "camera", AID_CAMERA, }, - { "log", AID_LOG, }, - { "compass", AID_COMPASS, }, - { "mount", AID_MOUNT, }, - { "wifi", AID_WIFI, }, - { "dhcp", AID_DHCP, }, - { "adb", AID_ADB, }, - { "install", AID_INSTALL, }, - { "media", AID_MEDIA, }, - { "shell", AID_SHELL, }, - { "cache", AID_CACHE, }, - { "diag", AID_DIAG, }, - { "net_bt_admin", AID_NET_BT_ADMIN, }, - { "net_bt", AID_NET_BT, }, - { "inet", AID_INET, }, - { "net_raw", AID_NET_RAW, }, - { "misc", AID_MISC, }, - { "nobody", AID_NOBODY, }, -}; - -#define android_id_count \ - (sizeof(android_ids) / sizeof(android_ids[0])) - -struct fs_path_config { - unsigned mode; - unsigned uid; - unsigned gid; - const char *prefix; -}; - -/* Rules for directories. -** These rules are applied based on "first match", so they -** should start with the most specific path and work their -** way up to the root. -*/ - -static struct fs_path_config android_dirs[] = { - { 00770, AID_SYSTEM, AID_CACHE, "cache" }, - { 00771, AID_SYSTEM, AID_SYSTEM, "data/app" }, - { 00771, AID_SYSTEM, AID_SYSTEM, "data/app-private" }, - { 00771, AID_SYSTEM, AID_SYSTEM, "data/dalvik-cache" }, - { 00771, AID_SYSTEM, AID_SYSTEM, "data/data" }, - { 00771, AID_SHELL, AID_SHELL, "data/local/tmp" }, - { 00771, AID_SHELL, AID_SHELL, "data/local" }, - { 01771, AID_SYSTEM, AID_MISC, "data/misc" }, - { 00770, AID_DHCP, AID_DHCP, "data/misc/dhcp" }, - { 00771, AID_SYSTEM, AID_SYSTEM, "data" }, - { 00750, AID_ROOT, AID_SHELL, "sbin" }, - { 00755, AID_ROOT, AID_SHELL, "system/bin" }, - { 00755, AID_ROOT, AID_SHELL, "system/xbin" }, - { 00777, AID_ROOT, AID_ROOT, "system/etc/ppp" }, /* REMOVE */ - { 00777, AID_ROOT, AID_ROOT, "sdcard" }, - { 00755, AID_ROOT, AID_ROOT, 0 }, -}; - -/* Rules for files. -** These rules are applied based on "first match", so they -** should start with the most specific path and work their -** way up to the root. Prefixes ending in * denotes wildcard -** and will allow partial matches. -*/ -static struct fs_path_config android_files[] = { - { 00555, AID_ROOT, AID_ROOT, "system/etc/ppp/ip-up" }, - { 00555, AID_ROOT, AID_ROOT, "system/etc/ppp/ip-down" }, - { 00440, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.rc" }, - { 00550, AID_ROOT, AID_SHELL, "system/etc/init.goldfish.sh" }, - { 00440, AID_ROOT, AID_SHELL, "system/etc/init.trout.rc" }, - { 00550, AID_ROOT, AID_SHELL, "system/etc/init.ril" }, - { 00550, AID_ROOT, AID_SHELL, "system/etc/init.testmenu" }, - { 00550, AID_ROOT, AID_SHELL, "system/etc/init.gprs-pppd" }, - { 00550, AID_DHCP, AID_SHELL, "system/etc/dhcpcd/dhcpcd-run-hooks" }, - { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/dbus.conf" }, - { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/hcid.conf" }, - { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/input.conf" }, - { 00440, AID_BLUETOOTH, AID_BLUETOOTH, "system/etc/bluez/audio.conf" }, - { 00440, AID_RADIO, AID_AUDIO, "/system/etc/AudioPara4.csv" }, - { 00644, AID_SYSTEM, AID_SYSTEM, "data/app/*" }, - { 00644, AID_SYSTEM, AID_SYSTEM, "data/app-private/*" }, - { 00644, AID_APP, AID_APP, "data/data/*" }, - /* the following two files are INTENTIONALLY set-gid and not set-uid. - * Do not change. */ - { 02755, AID_ROOT, AID_NET_RAW, "system/bin/ping" }, - { 02755, AID_ROOT, AID_INET, "system/bin/netcfg" }, - /* the following four files are INTENTIONALLY set-uid, but they - * are NOT included on user builds. */ - { 06755, AID_ROOT, AID_ROOT, "system/xbin/su" }, - { 06755, AID_ROOT, AID_ROOT, "system/xbin/librank" }, - { 06755, AID_ROOT, AID_ROOT, "system/xbin/procrank" }, - { 06755, AID_ROOT, AID_ROOT, "system/xbin/procmem" }, - { 00755, AID_ROOT, AID_SHELL, "system/bin/*" }, - { 00755, AID_ROOT, AID_SHELL, "system/xbin/*" }, - { 00750, AID_ROOT, AID_SHELL, "sbin/*" }, - { 00755, AID_ROOT, AID_ROOT, "bin/*" }, - { 00750, AID_ROOT, AID_SHELL, "init*" }, - { 00644, AID_ROOT, AID_ROOT, 0 }, -}; - -static inline void fs_config(const char *path, int dir, - unsigned *uid, unsigned *gid, unsigned *mode) -{ - struct fs_path_config *pc; - int plen; - - pc = dir ? android_dirs : android_files; - plen = strlen(path); - for(; pc->prefix; pc++){ - int len = strlen(pc->prefix); - if (dir) { - if(plen < len) continue; - if(!strncmp(pc->prefix, path, len)) break; - continue; - } - /* If name ends in * then allow partial matches. */ - if (pc->prefix[len -1] == '*') { - if(!strncmp(pc->prefix, path, len - 1)) break; - } else if (plen == len){ - if(!strncmp(pc->prefix, path, len)) break; - } - } - *uid = pc->uid; - *gid = pc->gid; - *mode = (*mode & (~07777)) | pc->mode; - -#if 0 - fprintf(stderr,"< '%s' '%s' %d %d %o >\n", - path, pc->prefix ? pc->prefix : "", *uid, *gid, *mode); -#endif -} -#endif -#endif diff --git a/include/private/pixelflinger/ggl_context.h b/include/private/pixelflinger/ggl_context.h deleted file mode 100644 index 3a030c526b32eacecb1a3b5614a08473faf8e196..0000000000000000000000000000000000000000 --- a/include/private/pixelflinger/ggl_context.h +++ /dev/null @@ -1,544 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_GGL_CONTEXT_H -#define ANDROID_GGL_CONTEXT_H - -#include <stdint.h> -#include <stddef.h> -#include <string.h> -#include <sys/types.h> - -#include <utils/Endian.h> -#include <pixelflinger/pixelflinger.h> -#include <private/pixelflinger/ggl_fixed.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -#if BYTE_ORDER == LITTLE_ENDIAN - -inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) { - return v; -} -inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) { - return v; -} - -#else - -inline uint32_t GGL_RGBA_TO_HOST(uint32_t v) { - return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00); -} -inline uint32_t GGL_HOST_TO_RGBA(uint32_t v) { - return (v<<24) | (v>>24) | ((v<<8)&0xff0000) | ((v>>8)&0xff00); -} - -#endif - -// ---------------------------------------------------------------------------- - -const int GGL_DITHER_BITS = 6; // dither weights stored on 6 bits -const int GGL_DITHER_ORDER_SHIFT= 3; -const int GGL_DITHER_ORDER = (1<<GGL_DITHER_ORDER_SHIFT); -const int GGL_DITHER_SIZE = GGL_DITHER_ORDER * GGL_DITHER_ORDER; -const int GGL_DITHER_MASK = GGL_DITHER_ORDER-1; - -// ---------------------------------------------------------------------------- - -const int GGL_SUBPIXEL_BITS = 4; - -// TRI_FRACTION_BITS defines the number of bits we want to use -// for the sub-pixel coordinates during the edge stepping, the -// value shouldn't be more than 7, or bad things are going to -// happen when drawing large triangles (8 doesn't work because -// 32 bit muls will loose the sign bit) - -#define TRI_FRACTION_BITS (GGL_SUBPIXEL_BITS) -#define TRI_ONE (1 << TRI_FRACTION_BITS) -#define TRI_HALF (1 << (TRI_FRACTION_BITS-1)) -#define TRI_FROM_INT(x) ((x) << TRI_FRACTION_BITS) -#define TRI_FRAC(x) ((x) & (TRI_ONE-1)) -#define TRI_FLOOR(x) ((x) & ~(TRI_ONE-1)) -#define TRI_CEIL(x) (((x) + (TRI_ONE-1)) & ~(TRI_ONE-1)) -#define TRI_ROUND(x) (((x) + TRI_HALF ) & ~(TRI_ONE-1)) - -#define TRI_ROUDNING (1 << (16 - TRI_FRACTION_BITS - 1)) -#define TRI_FROM_FIXED(x) (((x)+TRI_ROUDNING) >> (16-TRI_FRACTION_BITS)) - -#define TRI_SNAP_NEXT_HALF(x) (TRI_CEIL((x)+TRI_HALF) - TRI_HALF) -#define TRI_SNAP_PREV_HALF(x) (TRI_CEIL((x)-TRI_HALF) - TRI_HALF) - -// ---------------------------------------------------------------------------- - -const int GGL_COLOR_BITS = 24; - -// To maintain 8-bits color chanels, with a maximum GGLSurface -// size of 4096 and GGL_SUBPIXEL_BITS=4, we need 8 + 12 + 4 = 24 bits -// for encoding the color iterators - -inline GGLcolor gglFixedToIteratedColor(GGLfixed c) { - return (c << 8) - c; -} - -// ---------------------------------------------------------------------------- - -template<bool> struct CTA; -template<> struct CTA<true> { }; - -#define GGL_CONTEXT(con, c) context_t *con = static_cast<context_t *>(c) -#define GGL_OFFSETOF(field) int(&(((context_t*)0)->field)) -#define GGL_INIT_PROC(p, f) p.f = ggl_ ## f; -#define GGL_BETWEEN(x, L, H) (uint32_t((x)-(L)) <= ((H)-(L))) - -#define ggl_likely(x) __builtin_expect(!!(x), 1) -#define ggl_unlikely(x) __builtin_expect(!!(x), 0) - -const int GGL_TEXTURE_UNIT_COUNT = 2; -const int GGL_TMU_STATE = 0x00000001; -const int GGL_CB_STATE = 0x00000002; -const int GGL_PIXEL_PIPELINE_STATE = 0x00000004; - -// ---------------------------------------------------------------------------- - -#define GGL_RESERVE_NEEDS(name, l, s) \ - const uint32_t GGL_NEEDS_##name##_MASK = (((1LU<<(s))-1)<<l); \ - const uint32_t GGL_NEEDS_##name##_SHIFT = (l); - -#define GGL_BUILD_NEEDS(val, name) \ - (((val)<<(GGL_NEEDS_##name##_SHIFT)) & GGL_NEEDS_##name##_MASK) - -#define GGL_READ_NEEDS(name, n) \ - (uint32_t(n & GGL_NEEDS_##name##_MASK) >> GGL_NEEDS_##name##_SHIFT) - -#define GGL_NEED_MASK(name) (uint32_t(GGL_NEEDS_##name##_MASK)) -#define GGL_NEED(name, val) GGL_BUILD_NEEDS(val, name) - -GGL_RESERVE_NEEDS( CB_FORMAT, 0, 6 ) -GGL_RESERVE_NEEDS( SHADE, 6, 1 ) -GGL_RESERVE_NEEDS( W, 7, 1 ) -GGL_RESERVE_NEEDS( BLEND_SRC, 8, 4 ) -GGL_RESERVE_NEEDS( BLEND_DST, 12, 4 ) -GGL_RESERVE_NEEDS( BLEND_SRCA, 16, 4 ) -GGL_RESERVE_NEEDS( BLEND_DSTA, 20, 4 ) -GGL_RESERVE_NEEDS( LOGIC_OP, 24, 4 ) -GGL_RESERVE_NEEDS( MASK_ARGB, 28, 4 ) - -GGL_RESERVE_NEEDS( P_ALPHA_TEST, 0, 3 ) -GGL_RESERVE_NEEDS( P_AA, 3, 1 ) -GGL_RESERVE_NEEDS( P_DEPTH_TEST, 4, 3 ) -GGL_RESERVE_NEEDS( P_MASK_Z, 7, 1 ) -GGL_RESERVE_NEEDS( P_DITHER, 8, 1 ) -GGL_RESERVE_NEEDS( P_FOG, 9, 1 ) -GGL_RESERVE_NEEDS( P_RESERVED1, 10,22 ) - -GGL_RESERVE_NEEDS( T_FORMAT, 0, 6 ) -GGL_RESERVE_NEEDS( T_RESERVED0, 6, 1 ) -GGL_RESERVE_NEEDS( T_POT, 7, 1 ) -GGL_RESERVE_NEEDS( T_S_WRAP, 8, 2 ) -GGL_RESERVE_NEEDS( T_T_WRAP, 10, 2 ) -GGL_RESERVE_NEEDS( T_ENV, 12, 3 ) -GGL_RESERVE_NEEDS( T_LINEAR, 15, 1 ) - -const int GGL_NEEDS_WRAP_CLAMP_TO_EDGE = 0; -const int GGL_NEEDS_WRAP_REPEAT = 1; -const int GGL_NEEDS_WRAP_11 = 2; - -inline uint32_t ggl_wrap_to_needs(uint32_t e) { - switch (e) { - case GGL_CLAMP: return GGL_NEEDS_WRAP_CLAMP_TO_EDGE; - case GGL_REPEAT: return GGL_NEEDS_WRAP_REPEAT; - } - return 0; -} - -inline uint32_t ggl_blendfactor_to_needs(uint32_t b) { - if (b <= 1) return b; - return (b & 0xF)+2; -} - -inline uint32_t ggl_needs_to_blendfactor(uint32_t n) { - if (n <= 1) return n; - return (n - 2) + 0x300; -} - -inline uint32_t ggl_env_to_needs(uint32_t e) { - switch (e) { - case GGL_REPLACE: return 0; - case GGL_MODULATE: return 1; - case GGL_DECAL: return 2; - case GGL_BLEND: return 3; - case GGL_ADD: return 4; - } - return 0; -} - -inline uint32_t ggl_needs_to_env(uint32_t n) { - const uint32_t envs[] = { GGL_REPLACE, GGL_MODULATE, - GGL_DECAL, GGL_BLEND, GGL_ADD }; - return envs[n]; - -} - -// ---------------------------------------------------------------------------- - -enum { - GGL_ENABLE_BLENDING = 0x00000001, - GGL_ENABLE_SMOOTH = 0x00000002, - GGL_ENABLE_AA = 0x00000004, - GGL_ENABLE_LOGIC_OP = 0x00000008, - GGL_ENABLE_ALPHA_TEST = 0x00000010, - GGL_ENABLE_SCISSOR_TEST = 0x00000020, - GGL_ENABLE_TMUS = 0x00000040, - GGL_ENABLE_DEPTH_TEST = 0x00000080, - GGL_ENABLE_STENCIL_TEST = 0x00000100, - GGL_ENABLE_W = 0x00000200, - GGL_ENABLE_DITHER = 0x00000400, - GGL_ENABLE_FOG = 0x00000800, - GGL_ENABLE_POINT_AA_NICE= 0x00001000 -}; - -// ---------------------------------------------------------------------------- - -class needs_filter_t; -struct needs_t { - inline int match(const needs_filter_t& filter); - inline bool operator == (const needs_t& rhs) const { - return (n==rhs.n) && - (p==rhs.p) && - (t[0]==rhs.t[0]) && - (t[1]==rhs.t[1]); - } - inline bool operator != (const needs_t& rhs) const { - return !operator == (rhs); - } - uint32_t n; - uint32_t p; - uint32_t t[GGL_TEXTURE_UNIT_COUNT]; -}; - -inline int compare_type(const needs_t& lhs, const needs_t& rhs) { - return memcmp(&lhs, &rhs, sizeof(needs_t)); -} - -struct needs_filter_t { - needs_t value; - needs_t mask; -}; - -int needs_t::match(const needs_filter_t& filter) { - uint32_t result = - ((filter.value.n ^ n) & filter.mask.n) | - ((filter.value.p ^ p) & filter.mask.p) | - ((filter.value.t[0] ^ t[0]) & filter.mask.t[0]) | - ((filter.value.t[1] ^ t[1]) & filter.mask.t[1]); - return (result == 0); -} - -// ---------------------------------------------------------------------------- - -struct context_t; -class Assembly; - -struct blend_state_t { - uint32_t src; - uint32_t dst; - uint32_t src_alpha; - uint32_t dst_alpha; - uint8_t reserved; - uint8_t alpha_separate; - uint8_t operation; - uint8_t equation; -}; - -struct mask_state_t { - uint8_t color; - uint8_t depth; - uint32_t stencil; -}; - -struct clear_state_t { - GGLclampx r; - GGLclampx g; - GGLclampx b; - GGLclampx a; - GGLclampx depth; - GGLint stencil; - uint32_t colorPacked; - uint32_t depthPacked; - uint32_t stencilPacked; - uint32_t dirty; -}; - -struct fog_state_t { - uint8_t color[3]; - uint8_t reserved; -}; - -struct logic_op_state_t { - uint16_t opcode; -}; - -struct alpha_test_state_t { - uint16_t func; - GGLcolor ref; -}; - -struct depth_test_state_t { - uint16_t func; - GGLclampx clearValue; -}; - -struct scissor_t { - uint32_t user_left; - uint32_t user_right; - uint32_t user_top; - uint32_t user_bottom; - uint32_t left; - uint32_t right; - uint32_t top; - uint32_t bottom; -}; - -struct pixel_t { - uint32_t c[4]; - uint8_t s[4]; -}; - -struct surface_t { - union { - GGLSurface s; - struct { - uint32_t reserved; - uint32_t width; - uint32_t height; - int32_t stride; - uint8_t* data; - uint8_t format; - uint8_t dirty; - uint8_t pad[2]; - }; - }; - void (*read) (const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel); - void (*write)(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, const pixel_t* pixel); -}; - -// ---------------------------------------------------------------------------- - -struct texture_shade_t { - union { - struct { - int32_t is0; - int32_t idsdx; - int32_t idsdy; - int sscale; - int32_t it0; - int32_t idtdx; - int32_t idtdy; - int tscale; - }; - struct { - int32_t v; - int32_t dx; - int32_t dy; - int scale; - } st[2]; - }; -}; - -struct texture_iterators_t { - // these are not encoded in the same way than in the - // texture_shade_t structure - union { - struct { - GGLfixed ydsdy; - GGLfixed dsdx; - GGLfixed dsdy; - int sscale; - GGLfixed ydtdy; - GGLfixed dtdx; - GGLfixed dtdy; - int tscale; - }; - struct { - GGLfixed ydvdy; - GGLfixed dvdx; - GGLfixed dvdy; - int scale; - } st[2]; - }; -}; - -struct texture_t { - surface_t surface; - texture_iterators_t iterators; - texture_shade_t shade; - uint32_t s_coord; - uint32_t t_coord; - uint16_t s_wrap; - uint16_t t_wrap; - uint16_t min_filter; - uint16_t mag_filter; - uint16_t env; - uint8_t env_color[4]; - uint8_t enable; - uint8_t dirty; -}; - -struct raster_t { - GGLfixed x; - GGLfixed y; -}; - -struct framebuffer_t { - surface_t color; - surface_t read; - surface_t depth; - surface_t stencil; - int16_t *coverage; - size_t coverageBufferSize; -}; - -// ---------------------------------------------------------------------------- - -struct iterators_t { - int32_t xl; - int32_t xr; - int32_t y; - GGLcolor ydady; - GGLcolor ydrdy; - GGLcolor ydgdy; - GGLcolor ydbdy; - GGLfixed ydzdy; - GGLfixed ydwdy; - GGLfixed ydfdy; -}; - -struct shade_t { - GGLcolor a0; - GGLcolor dadx; - GGLcolor dady; - GGLcolor r0; - GGLcolor drdx; - GGLcolor drdy; - GGLcolor g0; - GGLcolor dgdx; - GGLcolor dgdy; - GGLcolor b0; - GGLcolor dbdx; - GGLcolor dbdy; - uint32_t z0; - GGLfixed32 dzdx; - GGLfixed32 dzdy; - GGLfixed w0; - GGLfixed dwdx; - GGLfixed dwdy; - uint32_t f0; - GGLfixed dfdx; - GGLfixed dfdy; -}; - -// these are used in the generated code -// we use this mirror structure to improve -// data locality in the pixel pipeline -struct generated_tex_vars_t { - uint32_t width; - uint32_t height; - uint32_t stride; - int32_t data; - int32_t dsdx; - int32_t dtdx; - int32_t spill[2]; -}; - -struct generated_vars_t { - struct { - int32_t c; - int32_t dx; - } argb[4]; - int32_t aref; - int32_t dzdx; - int32_t zbase; - int32_t f; - int32_t dfdx; - int32_t spill[3]; - generated_tex_vars_t texture[GGL_TEXTURE_UNIT_COUNT]; - int32_t rt; - int32_t lb; -}; - -// ---------------------------------------------------------------------------- - -struct state_t { - framebuffer_t buffers; - texture_t texture[GGL_TEXTURE_UNIT_COUNT]; - scissor_t scissor; - raster_t raster; - blend_state_t blend; - alpha_test_state_t alpha_test; - depth_test_state_t depth_test; - mask_state_t mask; - clear_state_t clear; - fog_state_t fog; - logic_op_state_t logic_op; - uint32_t enables; - uint32_t enabled_tmu; - needs_t needs; -}; - -// ---------------------------------------------------------------------------- - -struct context_t { - GGLContext procs; - state_t state; - shade_t shade; - iterators_t iterators; - generated_vars_t generated_vars __attribute__((aligned(32))); - uint8_t ditherMatrix[GGL_DITHER_SIZE] __attribute__((aligned(32))); - uint32_t packed; - uint32_t packed8888; - const GGLFormat* formats; - uint32_t dirty; - texture_t* activeTMU; - uint32_t activeTMUIndex; - - void (*init_y)(context_t* c, int32_t y); - void (*step_y)(context_t* c); - void (*scanline)(context_t* c); - void (*span)(context_t* c); - void (*rect)(context_t* c, size_t yc); - - void* base; - Assembly* scanline_as; - GGLenum error; -}; - -// ---------------------------------------------------------------------------- - -void ggl_init_context(context_t* context); -void ggl_uninit_context(context_t* context); -void ggl_error(context_t* c, GGLenum error); -int64_t ggl_system_time(); - -// ---------------------------------------------------------------------------- - -}; - -#endif // ANDROID_GGL_CONTEXT_H - diff --git a/include/private/pixelflinger/ggl_fixed.h b/include/private/pixelflinger/ggl_fixed.h deleted file mode 100644 index 96fdb32f11bc4a518167555f22b52a63bd6db25b..0000000000000000000000000000000000000000 --- a/include/private/pixelflinger/ggl_fixed.h +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_GGL_FIXED_H -#define ANDROID_GGL_FIXED_H - -#include <math.h> -#include <pixelflinger/pixelflinger.h> - -// ---------------------------------------------------------------------------- - -#define CONST __attribute__((const)) -#define ALWAYS_INLINE __attribute__((always_inline)) - -const GGLfixed FIXED_BITS = 16; -const GGLfixed FIXED_EPSILON = 1; -const GGLfixed FIXED_ONE = 1L<<FIXED_BITS; -const GGLfixed FIXED_HALF = 1L<<(FIXED_BITS-1); -const GGLfixed FIXED_MIN = 0x80000000L; -const GGLfixed FIXED_MAX = 0x7FFFFFFFL; - -inline GGLfixed gglIntToFixed(GGLfixed i) ALWAYS_INLINE ; -inline GGLfixed gglFixedToIntRound(GGLfixed f) ALWAYS_INLINE ; -inline GGLfixed gglFixedToIntFloor(GGLfixed f) ALWAYS_INLINE ; -inline GGLfixed gglFixedToIntCeil(GGLfixed f) ALWAYS_INLINE ; -inline GGLfixed gglFracx(GGLfixed v) ALWAYS_INLINE ; -inline GGLfixed gglFloorx(GGLfixed v) ALWAYS_INLINE ; -inline GGLfixed gglCeilx(GGLfixed v) ALWAYS_INLINE ; -inline GGLfixed gglCenterx(GGLfixed v) ALWAYS_INLINE ; -inline GGLfixed gglRoundx(GGLfixed v) ALWAYS_INLINE ; - -GGLfixed gglIntToFixed(GGLfixed i) { - return i<<FIXED_BITS; -} -GGLfixed gglFixedToIntRound(GGLfixed f) { - return (f + FIXED_HALF)>>FIXED_BITS; -} -GGLfixed gglFixedToIntFloor(GGLfixed f) { - return f>>FIXED_BITS; -} -GGLfixed gglFixedToIntCeil(GGLfixed f) { - return (f + ((1<<FIXED_BITS) - 1))>>FIXED_BITS; -} - -GGLfixed gglFracx(GGLfixed v) { - return v & ((1<<FIXED_BITS)-1); -} -GGLfixed gglFloorx(GGLfixed v) { - return gglFixedToIntFloor(v)<<FIXED_BITS; -} -GGLfixed gglCeilx(GGLfixed v) { - return gglFixedToIntCeil(v)<<FIXED_BITS; -} -GGLfixed gglCenterx(GGLfixed v) { - return gglFloorx(v + FIXED_HALF) | FIXED_HALF; -} -GGLfixed gglRoundx(GGLfixed v) { - return gglFixedToIntRound(v)<<FIXED_BITS; -} - -// conversion from (unsigned) int, short, byte to fixed... -#define GGL_B_TO_X(_x) GGLfixed( ((int32_t(_x)+1)>>1)<<10 ) -#define GGL_S_TO_X(_x) GGLfixed( ((int32_t(_x)+1)>>1)<<2 ) -#define GGL_I_TO_X(_x) GGLfixed( ((int32_t(_x)>>1)+1)>>14 ) -#define GGL_UB_TO_X(_x) GGLfixed( uint32_t(_x) + \ - (uint32_t(_x)<<8) + \ - (uint32_t(_x)>>7) ) -#define GGL_US_TO_X(_x) GGLfixed( (_x) + ((_x)>>15) ) -#define GGL_UI_TO_X(_x) GGLfixed( (((_x)>>1)+1)>>15 ) - -// ---------------------------------------------------------------------------- - -GGLfixed gglPowx(GGLfixed x, GGLfixed y) CONST; -GGLfixed gglSqrtx(GGLfixed a) CONST; -GGLfixed gglSqrtRecipx(GGLfixed x) CONST; -GGLfixed gglFastDivx(GGLfixed n, GGLfixed d) CONST; -int32_t gglMulDivi(int32_t a, int32_t b, int32_t c); - -int32_t gglRecipQNormalized(int32_t x, int* exponent); -int32_t gglRecipQ(GGLfixed x, int q) CONST; - -inline GGLfixed gglRecip(GGLfixed x) CONST; -inline GGLfixed gglRecip(GGLfixed x) { - return gglRecipQ(x, 16); -} - -inline GGLfixed gglRecip28(GGLfixed x) CONST; -int32_t gglRecip28(GGLfixed x) { - return gglRecipQ(x, 28); -} - -// ---------------------------------------------------------------------------- - -#if defined(__arm__) && !defined(__thumb__) - -// inline ARM implementations -inline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) CONST; -inline GGLfixed gglMulx(GGLfixed x, GGLfixed y, int shift) { - GGLfixed result, t; - if (__builtin_constant_p(shift)) { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "movs %[lo], %[lo], lsr %[rshift] \n" - "adc %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=r"(result), [hi]"=r"(t), [x]"=r"(x) - : "%[x]"(x), [y]"r"(y), [lshift] "I"(32-shift), [rshift] "I"(shift) - : "cc" - ); - } else { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "movs %[lo], %[lo], lsr %[rshift] \n" - "adc %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) - : "%[x]"(x), [y]"r"(y), [lshift] "r"(32-shift), [rshift] "r"(shift) - : "cc" - ); - } - return result; -} - -inline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; -inline GGLfixed gglMulAddx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) { - GGLfixed result, t; - if (__builtin_constant_p(shift)) { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "add %[lo], %[a], %[lo], lsr %[rshift] \n" - "add %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) - : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift) - ); - } else { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "add %[lo], %[a], %[lo], lsr %[rshift] \n" - "add %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) - : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift) - ); - } - return result; -} - -inline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) CONST; -inline GGLfixed gglMulSubx(GGLfixed x, GGLfixed y, GGLfixed a, int shift) { - GGLfixed result, t; - if (__builtin_constant_p(shift)) { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "rsb %[lo], %[a], %[lo], lsr %[rshift] \n" - "add %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) - : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "I"(32-shift), [rshift] "I"(shift) - ); - } else { - asm("smull %[lo], %[hi], %[x], %[y] \n" - "rsb %[lo], %[a], %[lo], lsr %[rshift] \n" - "add %[lo], %[lo], %[hi], lsl %[lshift] \n" - : [lo]"=&r"(result), [hi]"=&r"(t), [x]"=&r"(x) - : "%[x]"(x), [y]"r"(y), [a]"r"(a), [lshift] "r"(32-shift), [rshift] "r"(shift) - ); - } - return result; -} - -inline int64_t gglMulii(int32_t x, int32_t y) CONST; -inline int64_t gglMulii(int32_t x, int32_t y) -{ - // 64-bits result: r0=low, r1=high - union { - struct { - int32_t lo; - int32_t hi; - } s; - int64_t res; - }; - asm("smull %0, %1, %2, %3 \n" - : "=r"(s.lo), "=&r"(s.hi) - : "%r"(x), "r"(y) - : - ); - return res; -} - -#else // ---------------------------------------------------------------------- - -inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) CONST; -inline GGLfixed gglMulx(GGLfixed a, GGLfixed b, int shift) { - return GGLfixed((int64_t(a)*b + (1<<(shift-1)))>>shift); -} -inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; -inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { - return GGLfixed((int64_t(a)*b)>>shift) + c; -} -inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) CONST; -inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c, int shift) { - return GGLfixed((int64_t(a)*b)>>shift) - c; -} -inline int64_t gglMulii(int32_t a, int32_t b) CONST; -inline int64_t gglMulii(int32_t a, int32_t b) { - return int64_t(a)*b; -} - -#endif - -// ------------------------------------------------------------------------ - -inline GGLfixed gglMulx(GGLfixed a, GGLfixed b) CONST; -inline GGLfixed gglMulx(GGLfixed a, GGLfixed b) { - return gglMulx(a, b, 16); -} -inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; -inline GGLfixed gglMulAddx(GGLfixed a, GGLfixed b, GGLfixed c) { - return gglMulAddx(a, b, c, 16); -} -inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) CONST; -inline GGLfixed gglMulSubx(GGLfixed a, GGLfixed b, GGLfixed c) { - return gglMulSubx(a, b, c, 16); -} - -// ------------------------------------------------------------------------ - -inline int32_t gglClz(int32_t x) CONST; -inline int32_t gglClz(int32_t x) -{ -#if defined(__arm__) && !defined(__thumb__) - return __builtin_clz(x); -#else - if (!x) return 32; - int32_t exp = 31; - if (x & 0xFFFF0000) { exp -=16; x >>= 16; } - if (x & 0x0000ff00) { exp -= 8; x >>= 8; } - if (x & 0x000000f0) { exp -= 4; x >>= 4; } - if (x & 0x0000000c) { exp -= 2; x >>= 2; } - if (x & 0x00000002) { exp -= 1; } - return exp; -#endif -} - -// ------------------------------------------------------------------------ - -int32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) CONST; - -inline int32_t gglDivQ16(GGLfixed n, GGLfixed d) CONST; -inline int32_t gglDivQ16(GGLfixed n, GGLfixed d) { - return gglDivQ(n, d, 16); -} - -inline int32_t gglDivx(GGLfixed n, GGLfixed d) CONST; -inline int32_t gglDivx(GGLfixed n, GGLfixed d) { - return gglDivQ(n, d, 16); -} - -// ------------------------------------------------------------------------ - -inline GGLfixed gglRecipFast(GGLfixed x) CONST; -inline GGLfixed gglRecipFast(GGLfixed x) -{ - // This is a really bad approximation of 1/x, but it's also - // very fast. x must be strictly positive. - // if x between [0.5, 1[ , then 1/x = 3-2*x - // (we use 2.30 fixed-point) - const int32_t lz = gglClz(x); - return (0xC0000000 - (x << (lz - 1))) >> (30-lz); -} - -// ------------------------------------------------------------------------ - -inline GGLfixed gglClampx(GGLfixed c) CONST; -inline GGLfixed gglClampx(GGLfixed c) -{ -#if defined(__thumb__) - // clamp without branches - c &= ~(c>>31); c = FIXED_ONE - c; - c &= ~(c>>31); c = FIXED_ONE - c; -#else -#if defined(__arm__) - // I don't know why gcc thinks its smarter than me! The code below - // clamps to zero in one instruction, but gcc won't generate it and - // replace it by a cmp + movlt (it's quite amazing actually). - asm("bic %0, %1, %1, asr #31\n" : "=r"(c) : "r"(c)); -#else - c &= ~(c>>31); -#endif - if (c>FIXED_ONE) - c = FIXED_ONE; -#endif - return c; -} - -// ------------------------------------------------------------------------ - -#endif // ANDROID_GGL_FIXED_H diff --git a/include/zipfile/zipfile.h b/include/zipfile/zipfile.h deleted file mode 100644 index 0ae4ee4f94df05c6a326e78e9564f5bff65d48ed..0000000000000000000000000000000000000000 --- a/include/zipfile/zipfile.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _ZIPFILE_ZIPFILE_H -#define _ZIPFILE_ZIPFILE_H - -#include <stddef.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void* zipfile_t; -typedef void* zipentry_t; - -// Provide a buffer. Returns NULL on failure. -zipfile_t init_zipfile(const void* data, size_t size); - -// Release the zipfile resources. -void release_zipfile(zipfile_t file); - -// Get a named entry object. Returns NULL if it doesn't exist -// or if we won't be able to decompress it. The zipentry_t is -// freed by release_zipfile() -zipentry_t lookup_zipentry(zipfile_t file, const char* entryName); - -// Return the size of the entry. -size_t get_zipentry_size(zipentry_t entry); - -// return the filename of this entry, you own the memory returned -char* get_zipentry_name(zipentry_t entry); - -// The buffer must be 1.001 times the buffer size returned -// by get_zipentry_size. Returns nonzero on failure. -int decompress_zipentry(zipentry_t entry, void* buf, int bufsize); - -// iterate through the entries in the zip file. pass a pointer to -// a void* initialized to NULL to start. Returns NULL when done -zipentry_t iterate_zipfile(zipfile_t file, void** cookie); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _ZIPFILE_ZIPFILE_H diff --git a/init/Android.mk b/init/Android.mk deleted file mode 100644 index d3766d4556c62520a97c1686624cdb03d9d1be22..0000000000000000000000000000000000000000 --- a/init/Android.mk +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2005 The Android Open Source Project - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - builtins.c \ - init.c \ - devices.c \ - property_service.c \ - util.c \ - parser.c \ - logo.c - -ifeq ($(strip $(INIT_BOOTCHART)),true) -LOCAL_SRC_FILES += bootchart.c -LOCAL_CFLAGS += -DBOOTCHART=1 -endif - -LOCAL_MODULE:= init - -LOCAL_FORCE_STATIC_EXECUTABLE := true -LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT) -LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) - -LOCAL_STATIC_LIBRARIES := libcutils libc - -#LOCAL_STATIC_LIBRARIES := libcutils libc libminui libpixelflinger_static -#LOCAL_STATIC_LIBRARIES += libminzip libunz libamend libmtdutils libmincrypt -#LOCAL_STATIC_LIBRARIES += libstdc++_static - -include $(BUILD_EXECUTABLE) - diff --git a/init/MODULE_LICENSE_APACHE2 b/init/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/init/NOTICE b/init/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/init/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/init/README.BOOTCHART b/init/README.BOOTCHART deleted file mode 100644 index 70cf2c39bca288346c5e49d55401e609b00a02a4..0000000000000000000000000000000000000000 --- a/init/README.BOOTCHART +++ /dev/null @@ -1,52 +0,0 @@ -This version of init contains code to perform "bootcharting", i.e. generating log -files that can be later processed by the tools provided by www.bootchart.org. - -To activate it, you need to define build 'init' with the INIT_BOOTCHART environment -variable defined to 'true', for example: - - touch system/init/init.c - m INIT_BOOTCHART=true - -On the emulator, use the new -bootchart <timeout> option to boot with bootcharting -activated for <timeout> seconds. - -Otherwise, flash your device, and start it. Then create a file on the /data partition -with a command like the following: - - adb shell 'echo $TIMEOUT > /data/bootchart-start' - -Where the value of $TIMEOUT corresponds to the wanted bootcharted period in seconds; -for example, to bootchart for 2 minutes, do: - - adb shell 'echo 120 > /data/bootchart-start' - -Reboot your device, bootcharting will begin and stop after the period you gave. -You can also stop the bootcharting at any moment by doing the following: - - adb shell 'echo 1 > /data/bootchart-stop' - -Note that /data/bootchart-stop is deleted automatically by init at the end of the -bootcharting. This is not the case of /data/bootchart-start, so don't forget to delete it -when you're done collecting data: - - adb shell rm /data/bootchart-start - -The log files are placed in /data/bootchart/. you must run the script tools/grab-bootchart.sh -which will use ADB to retrieve them and create a bootchart.tgz file that can be used with -the bootchart parser/renderer, or even uploaded directly to the form located at: - - http://www.bootchart.org/download.html - -NOTE: the bootchart.org webform doesn't seem to work at the moment, you can generate an - image on your machine by doing the following: - - 1/ download the sources from www.bootchart.org - 2/ unpack them - 3/ in the source directory, type 'ant' to build the bootchart program - 4/ type 'java -jar bootchart.jar /path/to/bootchart.tgz - -technical note: - -this implementation of bootcharting does use the 'bootchartd' script provided by -www.bootchart.org, but a C re-implementation that is directly compiled into our init -program. diff --git a/init/bootchart.c b/init/bootchart.c deleted file mode 100644 index f72fcaaca06ea42e077ea984017dccbdfeb8a38c..0000000000000000000000000000000000000000 --- a/init/bootchart.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* this code is used to generate a boot sequence profile that can be used - * with the 'bootchart' graphics generation tool. see www.bootchart.org - * note that unlike the original bootchartd, this is not a Bash script but - * some C code that is run right from the init script. - */ - -#include <stdio.h> -#include <time.h> -#include <dirent.h> -#include <unistd.h> -#include <fcntl.h> -#include <unistd.h> -#include <fcntl.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <stdlib.h> -#include <sys/stat.h> -#include "bootchart.h" - -#define VERSION "0.8" -#define SAMPLE_PERIOD 0.2 -#define LOG_ROOT "/data/bootchart" -#define LOG_STAT LOG_ROOT"/proc_stat.log" -#define LOG_PROCS LOG_ROOT"/proc_ps.log" -#define LOG_DISK LOG_ROOT"/proc_diskstats.log" -#define LOG_HEADER LOG_ROOT"/header" -#define LOG_ACCT LOG_ROOT"/kernel_pacct" - -#define LOG_STARTFILE "/data/bootchart-start" -#define LOG_STOPFILE "/data/bootchart-stop" - -static int -unix_read(int fd, void* buff, int len) -{ - int ret; - do { ret = read(fd, buff, len); } while (ret < 0 && errno == EINTR); - return ret; -} - -static int -unix_write(int fd, const void* buff, int len) -{ - int ret; - do { ret = write(fd, buff, len); } while (ret < 0 && errno == EINTR); - return ret; -} - -static int -proc_read(const char* filename, char* buff, size_t buffsize) -{ - int len = 0; - int fd = open(filename, O_RDONLY); - if (fd >= 0) { - len = unix_read(fd, buff, buffsize-1); - close(fd); - } - buff[len > 0 ? len : 0] = 0; - return len; -} - -#define FILE_BUFF_SIZE 65536 - -typedef struct { - int count; - int fd; - char data[FILE_BUFF_SIZE]; -} FileBuffRec, *FileBuff; - -static void -file_buff_open( FileBuff buff, const char* path ) -{ - buff->count = 0; - buff->fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, 0755); -} - -static void -file_buff_write( FileBuff buff, const void* src, int len ) -{ - while (len > 0) { - int avail = sizeof(buff->data) - buff->count; - if (avail > len) - avail = len; - - memcpy( buff->data + buff->count, src, avail ); - len -= avail; - src = (char*)src + avail; - - buff->count += avail; - if (buff->count == FILE_BUFF_SIZE) { - unix_write( buff->fd, buff->data, buff->count ); - buff->count = 0; - } - } -} - -static void -file_buff_done( FileBuff buff ) -{ - if (buff->count > 0) { - unix_write( buff->fd, buff->data, buff->count ); - buff->count = 0; - } -} - -static void -log_header(void) -{ - FILE* out; - char cmdline[1024]; - char uname[128]; - char cpuinfo[128]; - char* cpu; - char date[32]; - time_t now_t = time(NULL); - struct tm now = *localtime(&now_t); - strftime(date, sizeof(date), "%x %X", &now); - - out = fopen( LOG_HEADER, "w" ); - if (out == NULL) - return; - - proc_read("/proc/cmdline", cmdline, sizeof(cmdline)); - proc_read("/proc/version", uname, sizeof(uname)); - proc_read("/proc/cpuinfo", cpuinfo, sizeof(cpuinfo)); - - cpu = strchr( cpuinfo, ':' ); - if (cpu) { - char* p = strchr(cpu, '\n'); - cpu += 2; - if (p) - *p = 0; - } - - fprintf(out, "version = %s\n", VERSION); - fprintf(out, "title = Boot chart for Android ( %s )\n", date); - fprintf(out, "system.uname = %s\n", uname); - fprintf(out, "system.release = 0.0\n"); - fprintf(out, "system.cpu = %s\n", cpu); - fprintf(out, "system.kernel.options = %s\n", cmdline); - fclose(out); -} - -static void -close_on_exec(int fd) -{ - fcntl(fd, F_SETFD, FD_CLOEXEC); -} - -static void -open_log_file(int* plogfd, const char* logfile) -{ - int logfd = *plogfd; - - /* create log file if needed */ - if (logfd < 0) - { - logfd = open(logfile,O_WRONLY|O_CREAT|O_TRUNC,0755); - if (logfd < 0) { - *plogfd = -2; - return; - } - close_on_exec(logfd); - *plogfd = logfd; - } -} - -static void -do_log_uptime(FileBuff log) -{ - char buff[65]; - int fd, ret, len; - - fd = open("/proc/uptime",O_RDONLY); - if (fd >= 0) { - int ret; - ret = unix_read(fd, buff, 64); - close(fd); - buff[64] = 0; - if (ret >= 0) { - long long jiffies = 100LL*strtod(buff,NULL); - int len; - snprintf(buff,sizeof(buff),"%lld\n",jiffies); - len = strlen(buff); - file_buff_write(log, buff, len); - } - } -} - -static void -do_log_ln(FileBuff log) -{ - file_buff_write(log, "\n", 1); -} - - -static void -do_log_file(FileBuff log, const char* procfile) -{ - char buff[1024]; - int fd; - - do_log_uptime(log); - - /* append file content */ - fd = open(procfile,O_RDONLY); - if (fd >= 0) { - close_on_exec(fd); - for (;;) { - int ret; - ret = unix_read(fd, buff, sizeof(buff)); - if (ret <= 0) - break; - - file_buff_write(log, buff, ret); - if (ret < (int)sizeof(buff)) - break; - } - close(fd); - } - - do_log_ln(log); -} - -static void -do_log_procs(FileBuff log) -{ - DIR* dir = opendir("/proc"); - struct dirent* entry; - - do_log_uptime(log); - - while ((entry = readdir(dir)) != NULL) { - /* only match numeric values */ - char* end; - int pid = strtol( entry->d_name, &end, 10); - if (end != NULL && end > entry->d_name && *end == 0) { - char filename[32]; - char buff[1024]; - char cmdline[1024]; - int len; - int fd; - - /* read command line and extract program name */ - snprintf(filename,sizeof(filename),"/proc/%d/cmdline",pid); - proc_read(filename, cmdline, sizeof(cmdline)); - - /* read process stat line */ - snprintf(filename,sizeof(filename),"/proc/%d/stat",pid); - fd = open(filename,O_RDONLY); - if (fd >= 0) { - len = unix_read(fd, buff, sizeof(buff)-1); - close(fd); - if (len > 0) { - int len2 = strlen(cmdline); - if (len2 > 0) { - /* we want to substitute the process name with its real name */ - const char* p1; - const char* p2; - buff[len] = 0; - p1 = strchr(buff, '('); - p2 = strchr(p1, ')'); - file_buff_write(log, buff, p1+1-buff); - file_buff_write(log, cmdline, strlen(cmdline)); - file_buff_write(log, p2, strlen(p2)); - } else { - /* no substitution */ - file_buff_write(log,buff,len); - } - } - } - } - } - closedir(dir); - do_log_ln(log); -} - -static FileBuffRec log_stat[1]; -static FileBuffRec log_procs[1]; -static FileBuffRec log_disks[1]; - -/* called to setup bootcharting */ -int bootchart_init( void ) -{ - int ret; - char buff[4]; - int timeout = 0, count = 0; - - buff[0] = 0; - proc_read( LOG_STARTFILE, buff, sizeof(buff) ); - if (buff[0] != 0) { - timeout = atoi(buff); - } - else { - /* when running with emulator, androidboot.bootchart=<timeout> - * might be passed by as kernel parameters to specify the bootchart - * timeout. this is useful when using -wipe-data since the /data - * partition is fresh - */ - char cmdline[1024]; - char* s; -#define KERNEL_OPTION "androidboot.bootchart=" - proc_read( "/proc/cmdline", cmdline, sizeof(cmdline) ); - s = strstr(cmdline, KERNEL_OPTION); - if (s) { - s += sizeof(KERNEL_OPTION)-1; - timeout = atoi(s); - } - } - if (timeout == 0) - return 0; - - if (timeout > BOOTCHART_MAX_TIME_SEC) - timeout = BOOTCHART_MAX_TIME_SEC; - - count = (timeout*1000 + BOOTCHART_POLLING_MS-1)/BOOTCHART_POLLING_MS; - - do {ret=mkdir(LOG_ROOT,0755);}while (ret < 0 && errno == EINTR); - - file_buff_open(log_stat, LOG_STAT); - file_buff_open(log_procs, LOG_PROCS); - file_buff_open(log_disks, LOG_DISK); - - /* create kernel process accounting file */ - { - int fd = open( LOG_ACCT, O_WRONLY|O_CREAT|O_TRUNC,0644); - if (fd >= 0) { - close(fd); - acct( LOG_ACCT ); - } - } - - log_header(); - return count; -} - -/* called each time you want to perform a bootchart sampling op */ -int bootchart_step( void ) -{ - do_log_file(log_stat, "/proc/stat"); - do_log_file(log_disks, "/proc/diskstats"); - do_log_procs(log_procs); - - /* we stop when /data/bootchart-stop contains 1 */ - { - char buff[2]; - if (proc_read(LOG_STOPFILE,buff,sizeof(buff)) > 0 && buff[0] == '1') { - return -1; - } - } - - return 0; -} - -void bootchart_finish( void ) -{ - unlink( LOG_STOPFILE ); - file_buff_done(log_stat); - file_buff_done(log_disks); - file_buff_done(log_procs); - acct(NULL); -} diff --git a/init/bootchart.h b/init/bootchart.h deleted file mode 100644 index 39d2d4f204bd1728e0cb2a14aeec9a533d8dcbd8..0000000000000000000000000000000000000000 --- a/init/bootchart.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _BOOTCHART_H -#define _BOOTCHART_H - -#ifndef BOOTCHART -# define BOOTCHART 0 -#endif - -#if BOOTCHART - -extern int bootchart_init(void); -extern int bootchart_step(void); -extern void bootchart_finish(void); - -# define BOOTCHART_POLLING_MS 200 /* polling period in ms */ -# define BOOTCHART_DEFAULT_TIME_SEC (2*60) /* default polling time in seconds */ -# define BOOTCHART_MAX_TIME_SEC (10*60) /* max polling time in seconds */ - -#endif /* BOOTCHART */ - -#endif /* _BOOTCHART_H */ diff --git a/init/builtins.c b/init/builtins.c deleted file mode 100644 index 95fb22304150b01027ec22faa174e6f93d55a72b..0000000000000000000000000000000000000000 --- a/init/builtins.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <string.h> -#include <stdio.h> -#include <linux/kd.h> -#include <errno.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <linux/if.h> -#include <arpa/inet.h> -#include <stdlib.h> -#include <sys/mount.h> -#include <sys/resource.h> - -#include "init.h" -#include "keywords.h" -#include "property_service.h" -#include "devices.h" - -#include <private/android_filesystem_config.h> - -void add_environment(const char *name, const char *value); - -extern int init_module(void *, unsigned long, const char *); - -static int write_file(const char *path, const char *value) -{ - int fd, ret, len; - - fd = open(path, O_WRONLY|O_CREAT, 0622); - - if (fd < 0) - return -1; - - len = strlen(value); - - do { - ret = write(fd, value, len); - } while (ret < 0 && errno == EINTR); - - close(fd); - if (ret < 0) { - return -1; - } else { - return 0; - } -} - -static int insmod(const char *filename, char *options) -{ - void *module; - unsigned size; - int ret; - - module = read_file(filename, &size); - if (!module) - return -1; - - ret = init_module(module, size, options); - - free(module); - - return ret; -} - -static int setkey(struct kbentry *kbe) -{ - int fd, ret; - - fd = open("/dev/tty0", O_RDWR | O_SYNC); - if (fd < 0) - return -1; - - ret = ioctl(fd, KDSKBENT, kbe); - - close(fd); - return ret; -} - -static int __ifupdown(const char *interface, int up) -{ - struct ifreq ifr; - int s, ret; - - strlcpy(ifr.ifr_name, interface, IFNAMSIZ); - - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) - return -1; - - ret = ioctl(s, SIOCGIFFLAGS, &ifr); - if (ret < 0) { - goto done; - } - - if (up) - ifr.ifr_flags |= IFF_UP; - else - ifr.ifr_flags &= ~IFF_UP; - - ret = ioctl(s, SIOCSIFFLAGS, &ifr); - -done: - close(s); - return ret; -} - -static void service_start_if_not_disabled(struct service *svc) -{ - if (!(svc->flags & SVC_DISABLED)) { - service_start(svc); - } -} - -int do_class_start(int nargs, char **args) -{ - /* Starting a class does not start services - * which are explicitly disabled. They must - * be started individually. - */ - service_for_each_class(args[1], service_start_if_not_disabled); - return 0; -} - -int do_class_stop(int nargs, char **args) -{ - service_for_each_class(args[1], service_stop); - return 0; -} - -int do_domainname(int nargs, char **args) -{ - return write_file("/proc/sys/kernel/domainname", args[1]); -} - -int do_exec(int nargs, char **args) -{ - return -1; -} - -int do_export(int nargs, char **args) -{ - add_environment(args[1], args[2]); - return 0; -} - -int do_hostname(int nargs, char **args) -{ - return write_file("/proc/sys/kernel/hostname", args[1]); -} - -int do_ifup(int nargs, char **args) -{ - return __ifupdown(args[1], 1); -} - - -static int do_insmod_inner(int nargs, char **args, int opt_len) -{ - char options[opt_len + 1]; - int i; - - options[0] = '\0'; - if (nargs > 2) { - strcpy(options, args[2]); - for (i = 3; i < nargs; ++i) { - strcat(options, " "); - strcat(options, args[i]); - } - } - - return insmod(args[1], options); -} - -int do_insmod(int nargs, char **args) -{ - int i; - int size = 0; - - if (nargs > 2) { - for (i = 2; i < nargs; ++i) - size += strlen(args[i]) + 1; - } - - return do_insmod_inner(nargs, args, size); -} - -int do_import(int nargs, char **args) -{ - return -1; -} - -int do_mkdir(int nargs, char **args) -{ - mode_t mode = 0755; - - /* mkdir <path> [mode] [owner] [group] */ - - if (nargs >= 3) { - mode = strtoul(args[2], 0, 8); - } - - if (mkdir(args[1], mode)) { - return -errno; - } - - if (nargs >= 4) { - uid_t uid = decode_uid(args[3]); - gid_t gid = -1; - - if (nargs == 5) { - gid = decode_uid(args[4]); - } - - if (chown(args[1], uid, gid)) { - return -errno; - } - } - - return 0; -} - -static struct { - const char *name; - unsigned flag; -} mount_flags[] = { - { "noatime", MS_NOATIME }, - { "nosuid", MS_NOSUID }, - { "nodev", MS_NODEV }, - { "nodiratime", MS_NODIRATIME }, - { "ro", MS_RDONLY }, - { "rw", 0 }, - { "remount", MS_REMOUNT }, - { "defaults", 0 }, - { 0, 0 }, -}; - -/* mount <type> <device> <path> <flags ...> <options> */ -int do_mount(int nargs, char **args) -{ - char tmp[64]; - char *source; - char *options = NULL; - unsigned flags = 0; - int n, i; - - for (n = 4; n < nargs; n++) { - for (i = 0; mount_flags[i].name; i++) { - if (!strcmp(args[n], mount_flags[i].name)) { - flags |= mount_flags[i].flag; - break; - } - } - - /* if our last argument isn't a flag, wolf it up as an option string */ - if (n + 1 == nargs && !mount_flags[i].name) - options = args[n]; - } - - source = args[2]; - if (!strncmp(source, "mtd@", 4)) { - n = mtd_name_to_number(source + 4); - if (n >= 0) { - sprintf(tmp, "/dev/block/mtdblock%d", n); - source = tmp; - } - } - return mount(source, args[3], args[1], flags, options); -} - -int do_setkey(int nargs, char **args) -{ - struct kbentry kbe; - kbe.kb_table = strtoul(args[1], 0, 0); - kbe.kb_index = strtoul(args[2], 0, 0); - kbe.kb_value = strtoul(args[3], 0, 0); - return setkey(&kbe); -} - -int do_setprop(int nargs, char **args) -{ - property_set(args[1], args[2]); - return 0; -} - -int do_setrlimit(int nargs, char **args) -{ - struct rlimit limit; - int resource; - resource = atoi(args[1]); - limit.rlim_cur = atoi(args[2]); - limit.rlim_max = atoi(args[3]); - return setrlimit(resource, &limit); -} - -int do_start(int nargs, char **args) -{ - struct service *svc; - svc = service_find_by_name(args[1]); - if (svc) { - service_start(svc); - } - return 0; -} - -int do_stop(int nargs, char **args) -{ - struct service *svc; - svc = service_find_by_name(args[1]); - if (svc) { - service_stop(svc); - } - return 0; -} - -int do_restart(int nargs, char **args) -{ - struct service *svc; - svc = service_find_by_name(args[1]); - if (svc) { - service_stop(svc); - service_start(svc); - } - return 0; -} - -int do_trigger(int nargs, char **args) -{ - return 0; -} - -int do_symlink(int nargs, char **args) -{ - return symlink(args[1], args[2]); -} - -int do_sysclktz(int nargs, char **args) -{ - struct timezone tz; - - if (nargs != 2) - return -1; - - memset(&tz, 0, sizeof(tz)); - tz.tz_minuteswest = atoi(args[1]); - if (settimeofday(NULL, &tz)) - return -1; - return 0; -} - -int do_write(int nargs, char **args) -{ - return write_file(args[1], args[2]); -} - -int do_chown(int nargs, char **args) { - /* GID is optional. */ - if (nargs == 3) { - if (chown(args[2], decode_uid(args[1]), -1) < 0) - return -errno; - } else if (nargs == 4) { - if (chown(args[3], decode_uid(args[1]), decode_uid(args[2]))) - return -errno; - } else { - return -1; - } - return 0; -} - -static mode_t get_mode(const char *s) { - mode_t mode = 0; - while (*s) { - if (*s >= '0' && *s <= '7') { - mode = (mode<<3) | (*s-'0'); - } else { - return -1; - } - s++; - } - return mode; -} - -int do_chmod(int nargs, char **args) { - mode_t mode = get_mode(args[1]); - if (chmod(args[2], mode) < 0) { - return -errno; - } - return 0; -} - -int do_loglevel(int nargs, char **args) { - if (nargs == 2) { - log_set_level(atoi(args[1])); - return 0; - } - return -1; -} - -int do_device(int nargs, char **args) { - int len; - char tmp[64]; - char *source = args[1]; - int prefix = 0; - - if (nargs != 5) - return -1; - /* Check for wildcard '*' at the end which indicates a prefix. */ - len = strlen(args[1]) - 1; - if (args[1][len] == '*') { - args[1][len] = '\0'; - prefix = 1; - } - /* If path starts with mtd@ lookup the mount number. */ - if (!strncmp(source, "mtd@", 4)) { - int n = mtd_name_to_number(source + 4); - if (n >= 0) { - snprintf(tmp, sizeof(tmp), "/dev/mtd/mtd%d", n); - source = tmp; - } - } - add_devperms_partners(source, get_mode(args[2]), decode_uid(args[3]), - decode_uid(args[4]), prefix); - return 0; -} diff --git a/init/devices.c b/init/devices.c deleted file mode 100644 index b1ef6ab2a97748b8aaddaf0a57bb8ff5292ff6ba..0000000000000000000000000000000000000000 --- a/init/devices.c +++ /dev/null @@ -1,626 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <fcntl.h> -#include <dirent.h> -#include <unistd.h> -#include <string.h> - -#include <sys/socket.h> -#include <sys/un.h> -#include <linux/netlink.h> -#include <private/android_filesystem_config.h> -#include <sys/time.h> -#include <asm/page.h> - -#include "init.h" -#include "devices.h" - -#define CMDLINE_PREFIX "/dev" -#define SYSFS_PREFIX "/sys" -#define FIRMWARE_DIR "/etc/firmware" -#define MAX_QEMU_PERM 6 - -struct uevent { - const char *action; - const char *path; - const char *subsystem; - const char *firmware; - int major; - int minor; -}; - -static int open_uevent_socket(void) -{ - struct sockaddr_nl addr; - int sz = 64*1024; // XXX larger? udev uses 16MB! - int s; - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = getpid(); - addr.nl_groups = 0xffffffff; - - s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - if(s < 0) - return -1; - - setsockopt(s, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)); - - if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(s); - return -1; - } - - return s; -} - -struct perms_ { - char *name; - mode_t perm; - unsigned int uid; - unsigned int gid; - unsigned short prefix; -}; -static struct perms_ devperms[] = { - { "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/full", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/ptmx", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/tty", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/random", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/urandom", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/ashmem", 0666, AID_ROOT, AID_ROOT, 0 }, - { "/dev/binder", 0666, AID_ROOT, AID_ROOT, 0 }, - - /* logger should be world writable (for logging) but not readable */ - { "/dev/log/", 0662, AID_ROOT, AID_LOG, 1 }, - - /* these should not be world writable */ - { "/dev/android_adb", 0660, AID_ADB, AID_ADB, 0 }, - { "/dev/android_adb_enable", 0660, AID_ADB, AID_ADB, 0 }, - { "/dev/ttyMSM0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 }, - { "/dev/ttyHS0", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 }, - { "/dev/uinput", 0600, AID_BLUETOOTH, AID_BLUETOOTH, 0 }, - { "/dev/alarm", 0664, AID_SYSTEM, AID_RADIO, 0 }, - { "/dev/tty0", 0660, AID_ROOT, AID_SYSTEM, 0 }, - { "/dev/graphics/", 0660, AID_ROOT, AID_GRAPHICS, 1 }, - { "/dev/hw3d", 0660, AID_SYSTEM, AID_GRAPHICS, 0 }, - { "/dev/input/", 0660, AID_ROOT, AID_INPUT, 1 }, - { "/dev/eac", 0660, AID_ROOT, AID_AUDIO, 0 }, - { "/dev/cam", 0660, AID_ROOT, AID_CAMERA, 0 }, - { "/dev/pmem", 0660, AID_SYSTEM, AID_GRAPHICS, 0 }, - { "/dev/pmem_gpu", 0660, AID_SYSTEM, AID_GRAPHICS, 1 }, - { "/dev/pmem_adsp", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/pmem_camera", 0660, AID_SYSTEM, AID_CAMERA, 1 }, - { "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 }, - { "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 }, - { "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 }, - { "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 }, - { "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 }, - { "/dev/msm_pcm_out", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/msm_pcm_in", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/msm_pcm_ctl", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/msm_snd", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/msm_mp3", 0660, AID_SYSTEM, AID_AUDIO, 1 }, - { "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 }, - { "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 }, - { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, - { "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 }, - { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, - { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, - { "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 }, - { NULL, 0, 0, 0, 0 }, -}; - -/* devperms_partners list and perm_node are for hardware specific /dev entries */ -struct perm_node { - struct perms_ dp; - struct listnode plist; -}; -list_declare(devperms_partners); - -/* - * Permission override when in emulator mode, must be parsed before - * system properties is initalized. - */ -static int qemu_perm_count; -static struct perms_ qemu_perms[MAX_QEMU_PERM + 1]; - -int add_devperms_partners(const char *name, mode_t perm, unsigned int uid, - unsigned int gid, unsigned short prefix) { - int size; - struct perm_node *node = malloc(sizeof (struct perm_node)); - if (!node) - return -ENOMEM; - - size = strlen(name) + 1; - if ((node->dp.name = malloc(size)) == NULL) - return -ENOMEM; - - memcpy(node->dp.name, name, size); - node->dp.perm = perm; - node->dp.uid = uid; - node->dp.gid = gid; - node->dp.prefix = prefix; - - list_add_tail(&devperms_partners, &node->plist); - return 0; -} - -void qemu_init(void) { - qemu_perm_count = 0; - memset(&qemu_perms, 0, sizeof(qemu_perms)); -} - -static int qemu_perm(const char* name, mode_t perm, unsigned int uid, - unsigned int gid, unsigned short prefix) -{ - char *buf; - if (qemu_perm_count == MAX_QEMU_PERM) - return -ENOSPC; - - buf = malloc(strlen(name) + 1); - if (!buf) - return -errno; - - strlcpy(buf, name, strlen(name) + 1); - qemu_perms[qemu_perm_count].name = buf; - qemu_perms[qemu_perm_count].perm = perm; - qemu_perms[qemu_perm_count].uid = uid; - qemu_perms[qemu_perm_count].gid = gid; - qemu_perms[qemu_perm_count].prefix = prefix; - - qemu_perm_count++; - return 0; -} - -/* Permission overrides for emulator that are parsed from /proc/cmdline. */ -void qemu_cmdline(const char* name, const char *value) -{ - char *buf; - if (!strcmp(name, "android.ril")) { - /* cmd line params currently assume /dev/ prefix */ - if (asprintf(&buf, CMDLINE_PREFIX"/%s", value) == -1) { - return; - } - INFO("nani- buf:: %s\n", buf); - qemu_perm(buf, 0660, AID_RADIO, AID_ROOT, 0); - } -} - -static int get_device_perm_inner(struct perms_ *perms, const char *path, - unsigned *uid, unsigned *gid, mode_t *perm) -{ - int i; - for(i = 0; perms[i].name; i++) { - - if(perms[i].prefix) { - if(strncmp(path, perms[i].name, strlen(perms[i].name))) - continue; - } else { - if(strcmp(path, perms[i].name)) - continue; - } - *uid = perms[i].uid; - *gid = perms[i].gid; - *perm = perms[i].perm; - return 0; - } - return -1; -} - -/* First checks for emulator specific permissions specified in /proc/cmdline. */ -static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid) -{ - mode_t perm; - - if (get_device_perm_inner(qemu_perms, path, uid, gid, &perm) == 0) { - return perm; - } else if (get_device_perm_inner(devperms, path, uid, gid, &perm) == 0) { - return perm; - } else { - struct listnode *node; - struct perm_node *perm_node; - struct perms_ *dp; - - /* Check partners list. */ - list_for_each(node, &devperms_partners) { - perm_node = node_to_item(node, struct perm_node, plist); - dp = &perm_node->dp; - - if (dp->prefix) { - if (strncmp(path, dp->name, strlen(dp->name))) - continue; - } else { - if (strcmp(path, dp->name)) - continue; - } - /* Found perm in partner list. */ - *uid = dp->uid; - *gid = dp->gid; - return dp->perm; - } - /* Default if nothing found. */ - *uid = 0; - *gid = 0; - return 0600; - } -} - -static void make_device(const char *path, int block, int major, int minor) -{ - unsigned uid; - unsigned gid; - mode_t mode; - dev_t dev; - - if(major > 255 || minor > 255) - return; - - mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); - dev = (major << 8) | minor; - mknod(path, mode, dev); - chown(path, uid, gid); -} - -#ifdef LOG_UEVENTS - -static inline suseconds_t get_usecs(void) -{ - struct timeval tv; - gettimeofday(&tv, 0); - return tv.tv_sec * (suseconds_t) 1000000 + tv.tv_usec; -} - -#define log_event_print(x...) INFO(x) - -#else - -#define log_event_print(fmt, args...) do { } while (0) -#define get_usecs() 0 - -#endif - -static void parse_event(const char *msg, struct uevent *uevent) -{ - uevent->action = ""; - uevent->path = ""; - uevent->subsystem = ""; - uevent->firmware = ""; - uevent->major = -1; - uevent->minor = -1; - - /* currently ignoring SEQNUM */ - while(*msg) { - if(!strncmp(msg, "ACTION=", 7)) { - msg += 7; - uevent->action = msg; - } else if(!strncmp(msg, "DEVPATH=", 8)) { - msg += 8; - uevent->path = msg; - } else if(!strncmp(msg, "SUBSYSTEM=", 10)) { - msg += 10; - uevent->subsystem = msg; - } else if(!strncmp(msg, "FIRMWARE=", 9)) { - msg += 9; - uevent->firmware = msg; - } else if(!strncmp(msg, "MAJOR=", 6)) { - msg += 6; - uevent->major = atoi(msg); - } else if(!strncmp(msg, "MINOR=", 6)) { - msg += 6; - uevent->minor = atoi(msg); - } - - /* advance to after the next \0 */ - while(*msg++) - ; - } - - log_event_print("event { '%s', '%s', '%s', '%s', %d, %d }\n", - uevent->action, uevent->path, uevent->subsystem, - uevent->firmware, uevent->major, uevent->minor); -} - -static void handle_device_event(struct uevent *uevent) -{ - char devpath[96]; - char *base, *name; - int block; - - /* if it's not a /dev device, nothing to do */ - if((uevent->major < 0) || (uevent->minor < 0)) - return; - - /* do we have a name? */ - name = strrchr(uevent->path, '/'); - if(!name) - return; - name++; - - /* too-long names would overrun our buffer */ - if(strlen(name) > 64) - return; - - /* are we block or char? where should we live? */ - if(!strncmp(uevent->subsystem, "block", 5)) { - block = 1; - base = "/dev/block/"; - mkdir(base, 0755); - } else { - block = 0; - /* this should probably be configurable somehow */ - if(!strncmp(uevent->subsystem, "graphics", 8)) { - base = "/dev/graphics/"; - mkdir(base, 0755); - } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) { - base = "/dev/oncrpc/"; - mkdir(base, 0755); - } else if (!strncmp(uevent->subsystem, "adsp", 4)) { - base = "/dev/adsp/"; - mkdir(base, 0755); - } else if(!strncmp(uevent->subsystem, "input", 5)) { - base = "/dev/input/"; - mkdir(base, 0755); - } else if(!strncmp(uevent->subsystem, "mtd", 3)) { - base = "/dev/mtd/"; - mkdir(base, 0755); - } else if(!strncmp(uevent->subsystem, "misc", 4) && - !strncmp(name, "log_", 4)) { - base = "/dev/log/"; - mkdir(base, 0755); - name += 4; - } else - base = "/dev/"; - } - - snprintf(devpath, sizeof(devpath), "%s%s", base, name); - - if(!strcmp(uevent->action, "add")) { - make_device(devpath, block, uevent->major, uevent->minor); - return; - } - - if(!strcmp(uevent->action, "remove")) { - unlink(devpath); - return; - } -} - -static int load_firmware(int fw_fd, int loading_fd, int data_fd) -{ - struct stat st; - long len_to_copy; - int ret = 0; - - if(fstat(fw_fd, &st) < 0) - return -1; - len_to_copy = st.st_size; - - write(loading_fd, "1", 1); /* start transfer */ - - while (len_to_copy > 0) { - char buf[PAGE_SIZE]; - ssize_t nr; - - nr = read(fw_fd, buf, sizeof(buf)); - if(!nr) - break; - if(nr < 0) { - ret = -1; - break; - } - - len_to_copy -= nr; - while (nr > 0) { - ssize_t nw = 0; - - nw = write(data_fd, buf + nw, nr); - if(nw <= 0) { - ret = -1; - goto out; - } - nr -= nw; - } - } - -out: - if(!ret) - write(loading_fd, "0", 1); /* successful end of transfer */ - else - write(loading_fd, "-1", 2); /* abort transfer */ - - return ret; -} - -static void process_firmware_event(struct uevent *uevent) -{ - char *root, *loading, *data, *file; - int l, loading_fd, data_fd, fw_fd; - - log_event_print("firmware event { '%s', '%s' }\n", - uevent->path, uevent->firmware); - - l = asprintf(&root, SYSFS_PREFIX"%s/", uevent->path); - if (l == -1) - return; - - l = asprintf(&loading, "%sloading", root); - if (l == -1) - goto root_free_out; - - l = asprintf(&data, "%sdata", root); - if (l == -1) - goto loading_free_out; - - l = asprintf(&file, FIRMWARE_DIR"/%s", uevent->firmware); - if (l == -1) - goto data_free_out; - - loading_fd = open(loading, O_WRONLY); - if(loading_fd < 0) - goto file_free_out; - - data_fd = open(data, O_WRONLY); - if(data_fd < 0) - goto loading_close_out; - - fw_fd = open(file, O_RDONLY); - if(fw_fd < 0) - goto data_close_out; - - if(!load_firmware(fw_fd, loading_fd, data_fd)) - log_event_print("firmware copy success { '%s', '%s' }\n", root, file); - else - log_event_print("firmware copy failure { '%s', '%s' }\n", root, file); - - close(fw_fd); -data_close_out: - close(data_fd); -loading_close_out: - close(loading_fd); -file_free_out: - free(file); -data_free_out: - free(data); -loading_free_out: - free(loading); -root_free_out: - free(root); -} - -static void handle_firmware_event(struct uevent *uevent) -{ - pid_t pid; - - if(strcmp(uevent->subsystem, "firmware")) - return; - - if(strcmp(uevent->action, "add")) - return; - - /* we fork, to avoid making large memory allocations in init proper */ - pid = fork(); - if (!pid) { - process_firmware_event(uevent); - exit(EXIT_SUCCESS); - } -} - -#define UEVENT_MSG_LEN 1024 -void handle_device_fd(int fd) -{ - char msg[UEVENT_MSG_LEN+2]; - int n; - - while((n = recv(fd, msg, UEVENT_MSG_LEN, 0)) > 0) { - struct uevent uevent; - - if(n == UEVENT_MSG_LEN) /* overflow -- discard */ - continue; - - msg[n] = '\0'; - msg[n+1] = '\0'; - - parse_event(msg, &uevent); - - handle_device_event(&uevent); - handle_firmware_event(&uevent); - } -} - -/* Coldboot walks parts of the /sys tree and pokes the uevent files -** to cause the kernel to regenerate device add events that happened -** before init's device manager was started -** -** We drain any pending events from the netlink socket every time -** we poke another uevent file to make sure we don't overrun the -** socket's buffer. -*/ - -static void do_coldboot(int event_fd, DIR *d) -{ - struct dirent *de; - int dfd, fd; - - dfd = dirfd(d); - - fd = openat(dfd, "uevent", O_WRONLY); - if(fd >= 0) { - write(fd, "add\n", 4); - close(fd); - handle_device_fd(event_fd); - } - - while((de = readdir(d))) { - DIR *d2; - - if(de->d_type != DT_DIR || de->d_name[0] == '.') - continue; - - fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY); - if(fd < 0) - continue; - - d2 = fdopendir(fd); - if(d2 == 0) - close(fd); - else { - do_coldboot(event_fd, d2); - closedir(d2); - } - } -} - -static void coldboot(int event_fd, const char *path) -{ - DIR *d = opendir(path); - if(d) { - do_coldboot(event_fd, d); - closedir(d); - } -} - -int device_init(void) -{ - suseconds_t t0, t1; - int fd; - - fd = open_uevent_socket(); - if(fd < 0) - return -1; - - fcntl(fd, F_SETFD, FD_CLOEXEC); - fcntl(fd, F_SETFL, O_NONBLOCK); - - t0 = get_usecs(); - coldboot(fd, "/sys/class"); - coldboot(fd, "/sys/block"); - coldboot(fd, "/sys/devices"); - t1 = get_usecs(); - - log_event_print("coldboot %ld uS\n", ((long) (t1 - t0))); - - return fd; -} diff --git a/init/devices.h b/init/devices.h deleted file mode 100644 index b484da45e3d26a1bd2285689a8d104a8585e018c..0000000000000000000000000000000000000000 --- a/init/devices.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _INIT_DEVICES_H -#define _INIT_DEVICES_H - -extern void handle_device_fd(int fd); -extern int device_init(void); -extern void qemu_init(void); -extern void qemu_cmdline(const char* name, const char *value); -extern int add_devperms_partners(const char *name, mode_t perm, unsigned int uid, - unsigned int gid, unsigned short prefix); - -#endif /* _INIT_DEVICES_H */ diff --git a/init/grab-bootchart.sh b/init/grab-bootchart.sh deleted file mode 100755 index 7fe890436aa5dae783e831f7ea2bb8c9d368c70c..0000000000000000000000000000000000000000 --- a/init/grab-bootchart.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -# -# this script is used to retrieve the bootchart log generated -# by init when compiled with INIT_BOOTCHART=true. -# -# for all details, see //device/system/init/README.BOOTCHART -# -TMPDIR=/tmp/android-bootchart -rm -rf $TMPDIR -mkdir -p $TMPDIR - -LOGROOT=/data/bootchart -TARBALL=bootchart.tgz - -FILES="header proc_stat.log proc_ps.log proc_diskstats.log kernel_pacct" - -for f in $FILES; do - adb pull $LOGROOT/$f $TMPDIR/$f 2>&1 > /dev/null -done -(cd $TMPDIR && tar -czf $TARBALL $FILES) -cp -f $TMPDIR/$TARBALL ./$TARBALL -echo "look at $TARBALL" diff --git a/init/init.c b/init/init.c deleted file mode 100644 index b8b4f4037724ac5a7713d5ca6f1289c4124f23c3..0000000000000000000000000000000000000000 --- a/init/init.c +++ /dev/null @@ -1,989 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <ctype.h> -#include <signal.h> -#include <sys/wait.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/poll.h> -#include <time.h> -#include <errno.h> -#include <stdarg.h> -#include <mtd/mtd-user.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/reboot.h> - -#include <cutils/sockets.h> -#include <termios.h> -#include <linux/kd.h> -#include <linux/keychord.h> - -#include <sys/system_properties.h> - -#include "devices.h" -#include "init.h" -#include "property_service.h" -#include "bootchart.h" - -static int property_triggers_enabled = 0; - -#if BOOTCHART -static int bootchart_count; -#endif - -static char console[32]; -static char serialno[32]; -static char bootmode[32]; -static char baseband[32]; -static char carrier[32]; -static char bootloader[32]; -static char hardware[32]; -static unsigned revision = 0; -static char qemu[32]; -static struct input_keychord *keychords = 0; -static int keychords_count = 0; -static int keychords_length = 0; - -static void drain_action_queue(void); - -static void notify_service_state(const char *name, const char *state) -{ - char pname[PROP_NAME_MAX]; - int len = strlen(name); - if ((len + 10) > PROP_NAME_MAX) - return; - snprintf(pname, sizeof(pname), "init.svc.%s", name); - property_set(pname, state); -} - -static int have_console; -static char *console_name = "/dev/console"; -static time_t process_needs_restart; - -static const char *ENV[32]; - -/* add_environment - add "key=value" to the current environment */ -int add_environment(const char *key, const char *val) -{ - int n; - - for (n = 0; n < 31; n++) { - if (!ENV[n]) { - size_t len = strlen(key) + strlen(val) + 2; - char *entry = malloc(len); - snprintf(entry, len, "%s=%s", key, val); - ENV[n] = entry; - return 0; - } - } - - return 1; -} - -static void zap_stdio(void) -{ - int fd; - fd = open("/dev/null", O_RDWR); - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); -} - -static void open_console() -{ - int fd; - if ((fd = open(console_name, O_RDWR)) < 0) { - fd = open("/dev/null", O_RDWR); - } - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - close(fd); -} - -/* - * gettime() - returns the time in seconds of the system's monotonic clock or - * zero on error. - */ -static time_t gettime(void) -{ - struct timespec ts; - int ret; - - ret = clock_gettime(CLOCK_MONOTONIC, &ts); - if (ret < 0) { - ERROR("clock_gettime(CLOCK_MONOTONIC) failed: %s\n", strerror(errno)); - return 0; - } - - return ts.tv_sec; -} - -static void publish_socket(const char *name, int fd) -{ - char key[64] = ANDROID_SOCKET_ENV_PREFIX; - char val[64]; - - strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1, - name, - sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX)); - snprintf(val, sizeof(val), "%d", fd); - add_environment(key, val); - - /* make sure we don't close-on-exec */ - fcntl(fd, F_SETFD, 0); -} - -void service_start(struct service *svc) -{ - struct stat s; - pid_t pid; - int needs_console; - int n; - - /* starting a service removes it from the disabled - * state and immediately takes it out of the restarting - * state if it was in there - */ - svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING)); - svc->time_started = 0; - - /* running processes require no additional work -- if - * they're in the process of exiting, we've ensured - * that they will immediately restart on exit, unless - * they are ONESHOT - */ - if (svc->flags & SVC_RUNNING) { - return; - } - - needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0; - if (needs_console && (!have_console)) { - ERROR("service '%s' requires console\n", svc->name); - svc->flags |= SVC_DISABLED; - return; - } - - if (stat(svc->args[0], &s) != 0) { - ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name); - svc->flags |= SVC_DISABLED; - return; - } - - NOTICE("starting '%s'\n", svc->name); - - pid = fork(); - - if (pid == 0) { - struct socketinfo *si; - struct svcenvinfo *ei; - char tmp[32]; - int fd, sz; - - get_property_workspace(&fd, &sz); - sprintf(tmp, "%d,%d", dup(fd), sz); - add_environment("ANDROID_PROPERTY_WORKSPACE", tmp); - - for (ei = svc->envvars; ei; ei = ei->next) - add_environment(ei->name, ei->value); - - for (si = svc->sockets; si; si = si->next) { - int s = create_socket(si->name, - !strcmp(si->type, "dgram") ? - SOCK_DGRAM : SOCK_STREAM, - si->perm, si->uid, si->gid); - if (s >= 0) { - publish_socket(si->name, s); - } - } - - if (needs_console) { - setsid(); - open_console(); - } else { - zap_stdio(); - } - -#if 0 - for (n = 0; svc->args[n]; n++) { - INFO("args[%d] = '%s'\n", n, svc->args[n]); - } - for (n = 0; ENV[n]; n++) { - INFO("env[%d] = '%s'\n", n, ENV[n]); - } -#endif - - setpgid(0, getpid()); - - /* as requested, set our gid, supplemental gids, and uid */ - if (svc->gid) { - setgid(svc->gid); - } - if (svc->nr_supp_gids) { - setgroups(svc->nr_supp_gids, svc->supp_gids); - } - if (svc->uid) { - setuid(svc->uid); - } - - execve(svc->args[0], (char**) svc->args, (char**) ENV); - _exit(127); - } - - if (pid < 0) { - ERROR("failed to start '%s'\n", svc->name); - svc->pid = 0; - return; - } - - svc->time_started = gettime(); - svc->pid = pid; - svc->flags |= SVC_RUNNING; - - notify_service_state(svc->name, "running"); -} - -void service_stop(struct service *svc) -{ - /* we are no longer running, nor should we - * attempt to restart - */ - svc->flags &= (~(SVC_RUNNING|SVC_RESTARTING)); - - /* if the service has not yet started, prevent - * it from auto-starting with its class - */ - svc->flags |= SVC_DISABLED; - - if (svc->pid) { - NOTICE("service '%s' is being killed\n", svc->name); - kill(-svc->pid, SIGTERM); - notify_service_state(svc->name, "stopping"); - } else { - notify_service_state(svc->name, "stopped"); - } -} - -void property_changed(const char *name, const char *value) -{ - if (property_triggers_enabled) { - queue_property_triggers(name, value); - drain_action_queue(); - } -} - -#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */ -#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/ - -static int wait_for_one_process(int block) -{ - pid_t pid; - int status; - struct service *svc; - struct socketinfo *si; - time_t now; - struct listnode *node; - struct command *cmd; - - while ( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 && errno == EINTR ); - if (pid <= 0) return -1; - INFO("waitpid returned pid %d, status = %08x\n", pid, status); - - svc = service_find_by_pid(pid); - if (!svc) { - ERROR("untracked pid %d exited\n", pid); - return 0; - } - - NOTICE("process '%s', pid %d exited\n", svc->name, pid); - - if (!(svc->flags & SVC_ONESHOT)) { - kill(-pid, SIGKILL); - NOTICE("process '%s' killing any children in process group\n", svc->name); - } - - /* remove any sockets we may have created */ - for (si = svc->sockets; si; si = si->next) { - char tmp[128]; - snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name); - unlink(tmp); - } - - svc->pid = 0; - svc->flags &= (~SVC_RUNNING); - - /* oneshot processes go into the disabled state on exit */ - if (svc->flags & SVC_ONESHOT) { - svc->flags |= SVC_DISABLED; - } - - /* disabled processes do not get restarted automatically */ - if (svc->flags & SVC_DISABLED) { - notify_service_state(svc->name, "stopped"); - return 0; - } - - now = gettime(); - if (svc->flags & SVC_CRITICAL) { - if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) { - if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) { - ERROR("critical process '%s' exited %d times in %d minutes; " - "rebooting into recovery mode\n", svc->name, - CRITICAL_CRASH_THRESHOLD, CRITICAL_CRASH_WINDOW / 60); - sync(); - __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, - LINUX_REBOOT_CMD_RESTART2, "recovery"); - return 0; - } - } else { - svc->time_crashed = now; - svc->nr_crashed = 1; - } - } - - /* Execute all onrestart commands for this service. */ - list_for_each(node, &svc->onrestart.commands) { - cmd = node_to_item(node, struct command, clist); - cmd->func(cmd->nargs, cmd->args); - } - svc->flags |= SVC_RESTARTING; - notify_service_state(svc->name, "restarting"); - return 0; -} - -static void restart_service_if_needed(struct service *svc) -{ - time_t next_start_time = svc->time_started + 5; - - if (next_start_time <= gettime()) { - svc->flags &= (~SVC_RESTARTING); - service_start(svc); - return; - } - - if ((next_start_time < process_needs_restart) || - (process_needs_restart == 0)) { - process_needs_restart = next_start_time; - } -} - -static void restart_processes() -{ - process_needs_restart = 0; - service_for_each_flags(SVC_RESTARTING, - restart_service_if_needed); -} - -static int signal_fd = -1; - -static void sigchld_handler(int s) -{ - write(signal_fd, &s, 1); -} - -static void msg_start(const char *name) -{ - struct service *svc = service_find_by_name(name); - - if (svc) { - service_start(svc); - } else { - ERROR("no such service '%s'\n", name); - } -} - -static void msg_stop(const char *name) -{ - struct service *svc = service_find_by_name(name); - - if (svc) { - service_stop(svc); - } else { - ERROR("no such service '%s'\n"); - } -} - -void handle_control_message(const char *msg, const char *arg) -{ - if (!strcmp(msg,"start")) { - msg_start(arg); - } else if (!strcmp(msg,"stop")) { - msg_stop(arg); - } else { - ERROR("unknown control msg '%s'\n", msg); - } -} - -#define MAX_MTD_PARTITIONS 16 - -static struct { - char name[16]; - int number; -} mtd_part_map[MAX_MTD_PARTITIONS]; - -static int mtd_part_count = -1; - -static void find_mtd_partitions(void) -{ - int fd; - char buf[1024]; - char *pmtdbufp; - ssize_t pmtdsize; - int r; - - fd = open("/proc/mtd", O_RDONLY); - if (fd < 0) - return; - - buf[sizeof(buf) - 1] = '\0'; - pmtdsize = read(fd, buf, sizeof(buf) - 1); - pmtdbufp = buf; - while (pmtdsize > 0) { - int mtdnum, mtdsize, mtderasesize; - char mtdname[16]; - mtdname[0] = '\0'; - mtdnum = -1; - r = sscanf(pmtdbufp, "mtd%d: %x %x %15s", - &mtdnum, &mtdsize, &mtderasesize, mtdname); - if ((r == 4) && (mtdname[0] == '"')) { - char *x = strchr(mtdname + 1, '"'); - if (x) { - *x = 0; - } - INFO("mtd partition %d, %s\n", mtdnum, mtdname + 1); - if (mtd_part_count < MAX_MTD_PARTITIONS) { - strcpy(mtd_part_map[mtd_part_count].name, mtdname + 1); - mtd_part_map[mtd_part_count].number = mtdnum; - mtd_part_count++; - } else { - ERROR("too many mtd partitions\n"); - } - } - while (pmtdsize > 0 && *pmtdbufp != '\n') { - pmtdbufp++; - pmtdsize--; - } - if (pmtdsize > 0) { - pmtdbufp++; - pmtdsize--; - } - } - close(fd); -} - -int mtd_name_to_number(const char *name) -{ - int n; - if (mtd_part_count < 0) { - mtd_part_count = 0; - find_mtd_partitions(); - } - for (n = 0; n < mtd_part_count; n++) { - if (!strcmp(name, mtd_part_map[n].name)) { - return mtd_part_map[n].number; - } - } - return -1; -} - -static void import_kernel_nv(char *name, int in_qemu) -{ - char *value = strchr(name, '='); - - if (value == 0) return; - *value++ = 0; - if (*name == 0) return; - - if (!in_qemu) - { - /* on a real device, white-list the kernel options */ - if (!strcmp(name,"qemu")) { - strlcpy(qemu, value, sizeof(qemu)); - } else if (!strcmp(name,"androidboot.console")) { - strlcpy(console, value, sizeof(console)); - } else if (!strcmp(name,"androidboot.mode")) { - strlcpy(bootmode, value, sizeof(bootmode)); - } else if (!strcmp(name,"androidboot.serialno")) { - strlcpy(serialno, value, sizeof(serialno)); - } else if (!strcmp(name,"androidboot.baseband")) { - strlcpy(baseband, value, sizeof(baseband)); - } else if (!strcmp(name,"androidboot.carrier")) { - strlcpy(carrier, value, sizeof(carrier)); - } else if (!strcmp(name,"androidboot.bootloader")) { - strlcpy(bootloader, value, sizeof(bootloader)); - } else if (!strcmp(name,"androidboot.hardware")) { - strlcpy(hardware, value, sizeof(hardware)); - } else { - qemu_cmdline(name, value); - } - } else { - /* in the emulator, export any kernel option with the - * ro.kernel. prefix */ - char buff[32]; - int len = snprintf( buff, sizeof(buff), "ro.kernel.%s", name ); - if (len < (int)sizeof(buff)) { - property_set( buff, value ); - } - } -} - -static void import_kernel_cmdline(int in_qemu) -{ - char cmdline[1024]; - char *ptr; - int fd; - - fd = open("/proc/cmdline", O_RDONLY); - if (fd >= 0) { - int n = read(fd, cmdline, 1023); - if (n < 0) n = 0; - - /* get rid of trailing newline, it happens */ - if (n > 0 && cmdline[n-1] == '\n') n--; - - cmdline[n] = 0; - close(fd); - } else { - cmdline[0] = 0; - } - - ptr = cmdline; - while (ptr && *ptr) { - char *x = strchr(ptr, ' '); - if (x != 0) *x++ = 0; - import_kernel_nv(ptr, in_qemu); - ptr = x; - } - - /* don't expose the raw commandline to nonpriv processes */ - chmod("/proc/cmdline", 0440); -} - -static void get_hardware_name(void) -{ - char data[1024]; - int fd, n; - char *x, *hw, *rev; - - /* Hardware string was provided on kernel command line */ - if (hardware[0]) - return; - - fd = open("/proc/cpuinfo", O_RDONLY); - if (fd < 0) return; - - n = read(fd, data, 1023); - close(fd); - if (n < 0) return; - - data[n] = 0; - hw = strstr(data, "\nHardware"); - rev = strstr(data, "\nRevision"); - - if (hw) { - x = strstr(hw, ": "); - if (x) { - x += 2; - n = 0; - while (*x && !isspace(*x)) { - hardware[n++] = tolower(*x); - x++; - if (n == 31) break; - } - hardware[n] = 0; - } - } - - if (rev) { - x = strstr(rev, ": "); - if (x) { - revision = strtoul(x + 2, 0, 16); - } - } -} - -static void drain_action_queue(void) -{ - struct listnode *node; - struct command *cmd; - struct action *act; - int ret; - - while ((act = action_remove_queue_head())) { - INFO("processing action %p (%s)\n", act, act->name); - list_for_each(node, &act->commands) { - cmd = node_to_item(node, struct command, clist); - ret = cmd->func(cmd->nargs, cmd->args); - INFO("command '%s' r=%d\n", cmd->args[0], ret); - } - } -} - -void open_devnull_stdio(void) -{ - int fd; - static const char *name = "/dev/__null__"; - if (mknod(name, S_IFCHR | 0600, (1 << 8) | 3) == 0) { - fd = open(name, O_RDWR); - unlink(name); - if (fd >= 0) { - dup2(fd, 0); - dup2(fd, 1); - dup2(fd, 2); - if (fd > 2) { - close(fd); - } - return; - } - } - - exit(1); -} - -void add_service_keycodes(struct service *svc) -{ - struct input_keychord *keychord; - int i, size; - - if (svc->keycodes) { - /* add a new keychord to the list */ - size = sizeof(*keychord) + svc->nkeycodes * sizeof(keychord->keycodes[0]); - keychords = realloc(keychords, keychords_length + size); - if (!keychords) { - ERROR("could not allocate keychords\n"); - keychords_length = 0; - keychords_count = 0; - return; - } - - keychord = (struct input_keychord *)((char *)keychords + keychords_length); - keychord->version = KEYCHORD_VERSION; - keychord->id = keychords_count + 1; - keychord->count = svc->nkeycodes; - svc->keychord_id = keychord->id; - - for (i = 0; i < svc->nkeycodes; i++) { - keychord->keycodes[i] = svc->keycodes[i]; - } - keychords_count++; - keychords_length += size; - } -} - -int open_keychord() -{ - int fd, ret; - - service_for_each(add_service_keycodes); - - /* nothing to do if no services require keychords */ - if (!keychords) - return -1; - - fd = open("/dev/keychord", O_RDWR); - if (fd < 0) { - ERROR("could not open /dev/keychord\n"); - return fd; - } - fcntl(fd, F_SETFD, FD_CLOEXEC); - - ret = write(fd, keychords, keychords_length); - if (ret != keychords_length) { - ERROR("could not configure /dev/keychord %d (%d)\n", ret, errno); - close(fd); - fd = -1; - } - - free(keychords); - keychords = 0; - - return fd; -} - -void handle_keychord(int fd) -{ - struct service *svc; - int ret; - __u16 id; - - ret = read(fd, &id, sizeof(id)); - if (ret != sizeof(id)) { - ERROR("could not read keychord id\n"); - return; - } - - svc = service_find_by_keychord(id); - if (svc) { - INFO("starting service %s from keychord\n", svc->name); - service_start(svc); - } else { - ERROR("service for keychord %d not found\n", id); - } -} - -int main(int argc, char **argv) -{ - int device_fd = -1; - int property_set_fd = -1; - int signal_recv_fd = -1; - int keychord_fd = -1; - int fd_count; - int s[2]; - int fd; - struct sigaction act; - char tmp[PROP_VALUE_MAX]; - struct pollfd ufds[4]; - char *tmpdev; - char* debuggable; - - act.sa_handler = sigchld_handler; - act.sa_flags = SA_NOCLDSTOP; - act.sa_mask = 0; - act.sa_restorer = NULL; - sigaction(SIGCHLD, &act, 0); - - /* clear the umask */ - umask(0); - - /* Get the basic filesystem setup we need put - * together in the initramdisk on / and then we'll - * let the rc file figure out the rest. - */ - mkdir("/dev", 0755); - mkdir("/proc", 0755); - mkdir("/sys", 0755); - - mount("tmpfs", "/dev", "tmpfs", 0, "mode=0755"); - mkdir("/dev/pts", 0755); - mkdir("/dev/socket", 0755); - mount("devpts", "/dev/pts", "devpts", 0, NULL); - mount("proc", "/proc", "proc", 0, NULL); - mount("sysfs", "/sys", "sysfs", 0, NULL); - - /* We must have some place other than / to create the - * device nodes for kmsg and null, otherwise we won't - * be able to remount / read-only later on. - * Now that tmpfs is mounted on /dev, we can actually - * talk to the outside world. - */ - open_devnull_stdio(); - log_init(); - - INFO("reading config file\n"); - parse_config_file("/init.rc"); - - /* pull the kernel commandline and ramdisk properties file in */ - qemu_init(); - import_kernel_cmdline(0); - - get_hardware_name(); - snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); - parse_config_file(tmp); - - action_for_each_trigger("early-init", action_add_queue_tail); - drain_action_queue(); - - INFO("device init\n"); - device_fd = device_init(); - - property_init(); - - // only listen for keychords if ro.debuggable is true - debuggable = property_get("ro.debuggable"); - if (debuggable && !strcmp(debuggable, "1")) { - keychord_fd = open_keychord(); - } - - if (console[0]) { - snprintf(tmp, sizeof(tmp), "/dev/%s", console); - console_name = strdup(tmp); - } - - fd = open(console_name, O_RDWR); - if (fd >= 0) - have_console = 1; - close(fd); - - if( load_565rle_image(INIT_IMAGE_FILE) ) { - fd = open("/dev/tty0", O_WRONLY); - if (fd >= 0) { - const char *msg; - msg = "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" // console is 40 cols x 30 lines - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - "\n" - " A N D R O I D "; - write(fd, msg, strlen(msg)); - close(fd); - } - } - - if (qemu[0]) - import_kernel_cmdline(1); - - if (!strcmp(bootmode,"factory")) - property_set("ro.factorytest", "1"); - else if (!strcmp(bootmode,"factory2")) - property_set("ro.factorytest", "2"); - else - property_set("ro.factorytest", "0"); - - property_set("ro.serialno", serialno[0] ? serialno : ""); - property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown"); - property_set("ro.baseband", baseband[0] ? baseband : "unknown"); - property_set("ro.carrier", carrier[0] ? carrier : "unknown"); - property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown"); - - property_set("ro.hardware", hardware); - snprintf(tmp, PROP_VALUE_MAX, "%d", revision); - property_set("ro.revision", tmp); - - /* execute all the boot actions to get us started */ - action_for_each_trigger("init", action_add_queue_tail); - drain_action_queue(); - - /* read any property files on system or data and - * fire up the property service. This must happen - * after the ro.foo properties are set above so - * that /data/local.prop cannot interfere with them. - */ - property_set_fd = start_property_service(); - - /* create a signalling mechanism for the sigchld handler */ - if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) { - signal_fd = s[0]; - signal_recv_fd = s[1]; - fcntl(s[0], F_SETFD, FD_CLOEXEC); - fcntl(s[0], F_SETFL, O_NONBLOCK); - fcntl(s[1], F_SETFD, FD_CLOEXEC); - fcntl(s[1], F_SETFL, O_NONBLOCK); - } - - /* make sure we actually have all the pieces we need */ - if ((device_fd < 0) || - (property_set_fd < 0) || - (signal_recv_fd < 0)) { - ERROR("init startup failure\n"); - return 1; - } - - /* execute all the boot actions to get us started */ - action_for_each_trigger("early-boot", action_add_queue_tail); - action_for_each_trigger("boot", action_add_queue_tail); - drain_action_queue(); - - /* run all property triggers based on current state of the properties */ - queue_all_property_triggers(); - drain_action_queue(); - - /* enable property triggers */ - property_triggers_enabled = 1; - - ufds[0].fd = device_fd; - ufds[0].events = POLLIN; - ufds[1].fd = property_set_fd; - ufds[1].events = POLLIN; - ufds[2].fd = signal_recv_fd; - ufds[2].events = POLLIN; - fd_count = 3; - - if (keychord_fd > 0) { - ufds[3].fd = keychord_fd; - ufds[3].events = POLLIN; - fd_count++; - } else { - ufds[3].events = 0; - ufds[3].revents = 0; - } - -#if BOOTCHART - bootchart_count = bootchart_init(); - if (bootchart_count < 0) { - ERROR("bootcharting init failure\n"); - } else if (bootchart_count > 0) { - NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS); - } else { - NOTICE("bootcharting ignored\n"); - } -#endif - - for(;;) { - int nr, i, timeout = -1; - - for (i = 0; i < fd_count; i++) - ufds[i].revents = 0; - - drain_action_queue(); - restart_processes(); - - if (process_needs_restart) { - timeout = (process_needs_restart - gettime()) * 1000; - if (timeout < 0) - timeout = 0; - } - -#if BOOTCHART - if (bootchart_count > 0) { - if (timeout < 0 || timeout > BOOTCHART_POLLING_MS) - timeout = BOOTCHART_POLLING_MS; - if (bootchart_step() < 0 || --bootchart_count == 0) { - bootchart_finish(); - bootchart_count = 0; - } - } -#endif - nr = poll(ufds, fd_count, timeout); - if (nr <= 0) - continue; - - if (ufds[2].revents == POLLIN) { - /* we got a SIGCHLD - reap and restart as needed */ - read(signal_recv_fd, tmp, sizeof(tmp)); - while (!wait_for_one_process(0)) - ; - continue; - } - - if (ufds[0].revents == POLLIN) - handle_device_fd(device_fd); - - if (ufds[1].revents == POLLIN) - handle_property_set_fd(property_set_fd); - if (ufds[3].revents == POLLIN) - handle_keychord(keychord_fd); - } - - return 0; -} diff --git a/init/init.h b/init/init.h deleted file mode 100644 index b68686930f6bdc69c1f03e02bc996d22df4b43c9..0000000000000000000000000000000000000000 --- a/init/init.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _INIT_INIT_H -#define _INIT_INIT_H - -int mtd_name_to_number(const char *name); - -void handle_control_message(const char *msg, const char *arg); - -int create_socket(const char *name, int type, mode_t perm, - uid_t uid, gid_t gid); - -void *read_file(const char *fn, unsigned *_sz); - -void log_init(void); -void log_set_level(int level); -void log_close(void); -void log_write(int level, const char *fmt, ...); - -#define ERROR(x...) log_write(3, "<3>init: " x) -#define NOTICE(x...) log_write(5, "<5>init: " x) -#define INFO(x...) log_write(6, "<6>init: " x) - -#define LOG_DEFAULT_LEVEL 3 /* messages <= this level are logged */ -#define LOG_UEVENTS 0 /* log uevent messages if 1. verbose */ - -unsigned int decode_uid(const char *s); - -struct listnode -{ - struct listnode *next; - struct listnode *prev; -}; - -#define node_to_item(node, container, member) \ - (container *) (((char*) (node)) - offsetof(container, member)) - -#define list_declare(name) \ - struct listnode name = { \ - .next = &name, \ - .prev = &name, \ - } - -#define list_for_each(node, list) \ - for (node = (list)->next; node != (list); node = node->next) - -void list_init(struct listnode *list); -void list_add_tail(struct listnode *list, struct listnode *item); -void list_remove(struct listnode *item); - -#define list_empty(list) ((list) == (list)->next) -#define list_head(list) ((list)->next) -#define list_tail(list) ((list)->prev) - -struct command -{ - /* list of commands in an action */ - struct listnode clist; - - int (*func)(int nargs, char **args); - int nargs; - char *args[1]; -}; - -struct action { - /* node in list of all actions */ - struct listnode alist; - /* node in the queue of pending actions */ - struct listnode qlist; - /* node in list of actions for a trigger */ - struct listnode tlist; - - unsigned hash; - const char *name; - - struct listnode commands; - struct command *current; -}; - -struct socketinfo { - struct socketinfo *next; - const char *name; - const char *type; - uid_t uid; - gid_t gid; - int perm; -}; - -struct svcenvinfo { - struct svcenvinfo *next; - const char *name; - const char *value; -}; - -#define SVC_DISABLED 0x01 /* do not autostart with class */ -#define SVC_ONESHOT 0x02 /* do not restart on exit */ -#define SVC_RUNNING 0x04 /* currently active */ -#define SVC_RESTARTING 0x08 /* waiting to restart */ -#define SVC_CONSOLE 0x10 /* requires console */ -#define SVC_CRITICAL 0x20 /* will reboot into recovery if keeps crashing */ - -#define NR_SVC_SUPP_GIDS 6 /* six supplementary groups */ - -struct service { - /* list of all services */ - struct listnode slist; - - const char *name; - const char *classname; - - unsigned flags; - pid_t pid; - time_t time_started; /* time of last start */ - time_t time_crashed; /* first crash within inspection window */ - int nr_crashed; /* number of times crashed within window */ - - uid_t uid; - gid_t gid; - gid_t supp_gids[NR_SVC_SUPP_GIDS]; - size_t nr_supp_gids; - - struct socketinfo *sockets; - struct svcenvinfo *envvars; - - int nargs; - char *args[1]; - struct action onrestart; /* Actions to execute on restart. */ - - /* keycodes for triggering this service via /dev/keychord */ - int *keycodes; - int nkeycodes; - int keychord_id; -}; - -int parse_config_file(const char *fn); - -struct service *service_find_by_name(const char *name); -struct service *service_find_by_pid(pid_t pid); -struct service *service_find_by_keychord(int keychord_id); -void service_for_each(void (*func)(struct service *svc)); -void service_for_each_class(const char *classname, - void (*func)(struct service *svc)); -void service_for_each_flags(unsigned matchflags, - void (*func)(struct service *svc)); -void service_stop(struct service *svc); -void service_start(struct service *svc); -void property_changed(const char *name, const char *value); - -struct action *action_remove_queue_head(void); -void action_add_queue_tail(struct action *act); -void action_for_each_trigger(const char *trigger, - void (*func)(struct action *act)); -void queue_property_triggers(const char *name, const char *value); -void queue_all_property_triggers(); - -#define INIT_IMAGE_FILE "/initlogo.rle" - -int load_565rle_image( char *file_name ); - -#endif /* _INIT_INIT_H */ diff --git a/init/keywords.h b/init/keywords.h deleted file mode 100644 index 6f47379c615898e24e0016bd58f7471efd40d70a..0000000000000000000000000000000000000000 --- a/init/keywords.h +++ /dev/null @@ -1,78 +0,0 @@ - -#ifndef KEYWORD -int do_class_start(int nargs, char **args); -int do_class_stop(int nargs, char **args); -int do_domainname(int nargs, char **args); -int do_exec(int nargs, char **args); -int do_export(int nargs, char **args); -int do_hostname(int nargs, char **args); -int do_ifup(int nargs, char **args); -int do_insmod(int nargs, char **args); -int do_import(int nargs, char **args); -int do_mkdir(int nargs, char **args); -int do_mount(int nargs, char **args); -int do_restart(int nargs, char **args); -int do_setkey(int nargs, char **args); -int do_setprop(int nargs, char **args); -int do_setrlimit(int nargs, char **args); -int do_start(int nargs, char **args); -int do_stop(int nargs, char **args); -int do_trigger(int nargs, char **args); -int do_symlink(int nargs, char **args); -int do_sysclktz(int nargs, char **args); -int do_write(int nargs, char **args); -int do_chown(int nargs, char **args); -int do_chmod(int nargs, char **args); -int do_loglevel(int nargs, char **args); -int do_device(int nargs, char **args); -#define __MAKE_KEYWORD_ENUM__ -#define KEYWORD(symbol, flags, nargs, func) K_##symbol, -enum { - K_UNKNOWN, -#endif - KEYWORD(capability, OPTION, 0, 0) - KEYWORD(class, OPTION, 0, 0) - KEYWORD(class_start, COMMAND, 1, do_class_start) - KEYWORD(class_stop, COMMAND, 1, do_class_stop) - KEYWORD(console, OPTION, 0, 0) - KEYWORD(critical, OPTION, 0, 0) - KEYWORD(disabled, OPTION, 0, 0) - KEYWORD(domainname, COMMAND, 1, do_domainname) - KEYWORD(exec, COMMAND, 1, do_exec) - KEYWORD(export, COMMAND, 2, do_export) - KEYWORD(group, OPTION, 0, 0) - KEYWORD(hostname, COMMAND, 1, do_hostname) - KEYWORD(ifup, COMMAND, 1, do_ifup) - KEYWORD(insmod, COMMAND, 1, do_insmod) - KEYWORD(import, COMMAND, 1, do_import) - KEYWORD(keycodes, OPTION, 0, 0) - KEYWORD(mkdir, COMMAND, 1, do_mkdir) - KEYWORD(mount, COMMAND, 3, do_mount) - KEYWORD(on, SECTION, 0, 0) - KEYWORD(oneshot, OPTION, 0, 0) - KEYWORD(onrestart, OPTION, 0, 0) - KEYWORD(restart, COMMAND, 1, do_restart) - KEYWORD(service, SECTION, 0, 0) - KEYWORD(setenv, OPTION, 2, 0) - KEYWORD(setkey, COMMAND, 0, do_setkey) - KEYWORD(setprop, COMMAND, 2, do_setprop) - KEYWORD(setrlimit, COMMAND, 3, do_setrlimit) - KEYWORD(socket, OPTION, 0, 0) - KEYWORD(start, COMMAND, 1, do_start) - KEYWORD(stop, COMMAND, 1, do_stop) - KEYWORD(trigger, COMMAND, 1, do_trigger) - KEYWORD(symlink, COMMAND, 1, do_symlink) - KEYWORD(sysclktz, COMMAND, 1, do_sysclktz) - KEYWORD(user, OPTION, 0, 0) - KEYWORD(write, COMMAND, 2, do_write) - KEYWORD(chown, COMMAND, 2, do_chown) - KEYWORD(chmod, COMMAND, 2, do_chmod) - KEYWORD(loglevel, COMMAND, 1, do_loglevel) - KEYWORD(device, COMMAND, 4, do_device) -#ifdef __MAKE_KEYWORD_ENUM__ - KEYWORD_COUNT, -}; -#undef __MAKE_KEYWORD_ENUM__ -#undef KEYWORD -#endif - diff --git a/init/logo.c b/init/logo.c deleted file mode 100644 index 6a740bfd61f8d3e4b0dd0d0b0e871fe2d9b78bbc..0000000000000000000000000000000000000000 --- a/init/logo.c +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <linux/fb.h> -#include <linux/kd.h> - -#include "init.h" - -#ifdef ANDROID -#include <cutils/memory.h> -#else -void android_memset16(void *_ptr, unsigned short val, unsigned count) -{ - unsigned short *ptr = _ptr; - count >>= 1; - while(count--) - *ptr++ = val; -} -#endif - -struct FB { - unsigned short *bits; - unsigned size; - int fd; - struct fb_fix_screeninfo fi; - struct fb_var_screeninfo vi; -}; - -#define fb_width(fb) ((fb)->vi.xres) -#define fb_height(fb) ((fb)->vi.yres) -#define fb_size(fb) ((fb)->vi.xres * (fb)->vi.yres * 2) - -static int fb_open(struct FB *fb) -{ - fb->fd = open("/dev/graphics/fb0", O_RDWR); - if (fb->fd < 0) - return -1; - - if (ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) - goto fail; - if (ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) - goto fail; - - fb->bits = mmap(0, fb_size(fb), PROT_READ | PROT_WRITE, - MAP_SHARED, fb->fd, 0); - if (fb->bits == MAP_FAILED) - goto fail; - - return 0; - -fail: - close(fb->fd); - return -1; -} - -static void fb_close(struct FB *fb) -{ - munmap(fb->bits, fb_size(fb)); - close(fb->fd); -} - -/* there's got to be a more portable way to do this ... */ -static void fb_update(struct FB *fb) -{ - fb->vi.yoffset = 1; - ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi); - fb->vi.yoffset = 0; - ioctl(fb->fd, FBIOPUT_VSCREENINFO, &fb->vi); -} - -static int vt_set_mode(int graphics) -{ - int fd, r; - fd = open("/dev/tty0", O_RDWR | O_SYNC); - if (fd < 0) - return -1; - r = ioctl(fd, KDSETMODE, (void*) (graphics ? KD_GRAPHICS : KD_TEXT)); - close(fd); - return r; -} - -/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */ - -int load_565rle_image(char *fn) -{ - struct FB fb; - struct stat s; - unsigned short *data, *bits, *ptr; - unsigned count, max; - int fd; - - if (vt_set_mode(1)) - return -1; - - fd = open(fn, O_RDONLY); - if (fd < 0) { - ERROR("cannot open '%s'\n", fn); - goto fail_restore_text; - } - - if (fstat(fd, &s) < 0) { - goto fail_close_file; - } - - data = mmap(0, s.st_size, PROT_READ, MAP_SHARED, fd, 0); - if (data == MAP_FAILED) - goto fail_close_file; - - if (fb_open(&fb)) - goto fail_unmap_data; - - max = fb_width(&fb) * fb_height(&fb); - ptr = data; - count = s.st_size; - bits = fb.bits; - while (count > 3) { - unsigned n = ptr[0]; - if (n > max) - break; - android_memset16(bits, ptr[1], n << 1); - bits += n; - max -= n; - ptr += 2; - count -= 4; - } - - munmap(data, s.st_size); - fb_update(&fb); - fb_close(&fb); - close(fd); - unlink(fn); - return 0; - -fail_unmap_data: - munmap(data, s.st_size); -fail_close_file: - close(fd); -fail_restore_text: - vt_set_mode(0); - return -1; -} - diff --git a/init/parser.c b/init/parser.c deleted file mode 100644 index 6a22d242de708e668477798c156d47260fe2c737..0000000000000000000000000000000000000000 --- a/init/parser.c +++ /dev/null @@ -1,797 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <stdarg.h> -#include <string.h> -#include <stddef.h> -#include <ctype.h> - -#include "init.h" -#include "property_service.h" - -#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ -#include <sys/_system_properties.h> - -static list_declare(service_list); -static list_declare(action_list); -static list_declare(action_queue); - -#define RAW(x...) log_write(6, x) - -void DUMP(void) -{ -#if 0 - struct service *svc; - struct action *act; - struct command *cmd; - struct listnode *node; - struct listnode *node2; - struct socketinfo *si; - int n; - - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - RAW("service %s\n", svc->name); - RAW(" class '%s'\n", svc->classname); - RAW(" exec"); - for (n = 0; n < svc->nargs; n++) { - RAW(" '%s'", svc->args[n]); - } - RAW("\n"); - for (si = svc->sockets; si; si = si->next) { - RAW(" socket %s %s 0%o\n", si->name, si->type, si->perm); - } - } - - list_for_each(node, &action_list) { - act = node_to_item(node, struct action, alist); - RAW("on %s\n", act->name); - list_for_each(node2, &act->commands) { - cmd = node_to_item(node2, struct command, clist); - RAW(" %p", cmd->func); - for (n = 0; n < cmd->nargs; n++) { - RAW(" %s", cmd->args[n]); - } - RAW("\n"); - } - RAW("\n"); - } -#endif -} - -#define MAXARGS 64 - -#define T_EOF 0 -#define T_TEXT 1 -#define T_NEWLINE 2 - -struct parse_state -{ - char *ptr; - char *text; - int line; - int nexttoken; - void *context; - void (*parse_line)(struct parse_state *state, int nargs, char **args); - const char *filename; -}; - -static void *parse_service(struct parse_state *state, int nargs, char **args); -static void parse_line_service(struct parse_state *state, int nargs, char **args); - -static void *parse_action(struct parse_state *state, int nargs, char **args); -static void parse_line_action(struct parse_state *state, int nargs, char **args); - -void parse_error(struct parse_state *state, const char *fmt, ...) -{ - va_list ap; - char buf[128]; - int off; - - snprintf(buf, 128, "%s: %d: ", state->filename, state->line); - buf[127] = 0; - off = strlen(buf); - - va_start(ap, fmt); - vsnprintf(buf + off, 128 - off, fmt, ap); - va_end(ap); - buf[127] = 0; - ERROR("%s", buf); -} - -#define SECTION 0x01 -#define COMMAND 0x02 -#define OPTION 0x04 - -#include "keywords.h" - -#define KEYWORD(symbol, flags, nargs, func) \ - [ K_##symbol ] = { #symbol, func, nargs + 1, flags, }, - -struct { - const char *name; - int (*func)(int nargs, char **args); - unsigned char nargs; - unsigned char flags; -} keyword_info[KEYWORD_COUNT] = { - [ K_UNKNOWN ] = { "unknown", 0, 0, 0 }, -#include "keywords.h" -}; -#undef KEYWORD - -#define kw_is(kw, type) (keyword_info[kw].flags & (type)) -#define kw_name(kw) (keyword_info[kw].name) -#define kw_func(kw) (keyword_info[kw].func) -#define kw_nargs(kw) (keyword_info[kw].nargs) - -int lookup_keyword(const char *s) -{ - switch (*s++) { - case 'c': - if (!strcmp(s, "apability")) return K_capability; - if (!strcmp(s, "lass")) return K_class; - if (!strcmp(s, "lass_start")) return K_class_start; - if (!strcmp(s, "lass_stop")) return K_class_stop; - if (!strcmp(s, "onsole")) return K_console; - if (!strcmp(s, "hown")) return K_chown; - if (!strcmp(s, "hmod")) return K_chmod; - if (!strcmp(s, "ritical")) return K_critical; - break; - case 'd': - if (!strcmp(s, "isabled")) return K_disabled; - if (!strcmp(s, "omainname")) return K_domainname; - if (!strcmp(s, "evice")) return K_device; - break; - case 'e': - if (!strcmp(s, "xec")) return K_exec; - if (!strcmp(s, "xport")) return K_export; - break; - case 'g': - if (!strcmp(s, "roup")) return K_group; - break; - case 'h': - if (!strcmp(s, "ostname")) return K_hostname; - break; - case 'i': - if (!strcmp(s, "fup")) return K_ifup; - if (!strcmp(s, "nsmod")) return K_insmod; - if (!strcmp(s, "mport")) return K_import; - break; - case 'k': - if (!strcmp(s, "eycodes")) return K_keycodes; - break; - case 'l': - if (!strcmp(s, "oglevel")) return K_loglevel; - break; - case 'm': - if (!strcmp(s, "kdir")) return K_mkdir; - if (!strcmp(s, "ount")) return K_mount; - break; - case 'o': - if (!strcmp(s, "n")) return K_on; - if (!strcmp(s, "neshot")) return K_oneshot; - if (!strcmp(s, "nrestart")) return K_onrestart; - break; - case 'r': - if (!strcmp(s, "estart")) return K_restart; - break; - case 's': - if (!strcmp(s, "ervice")) return K_service; - if (!strcmp(s, "etenv")) return K_setenv; - if (!strcmp(s, "etkey")) return K_setkey; - if (!strcmp(s, "etprop")) return K_setprop; - if (!strcmp(s, "etrlimit")) return K_setrlimit; - if (!strcmp(s, "ocket")) return K_socket; - if (!strcmp(s, "tart")) return K_start; - if (!strcmp(s, "top")) return K_stop; - if (!strcmp(s, "ymlink")) return K_symlink; - if (!strcmp(s, "ysclktz")) return K_sysclktz; - break; - case 't': - if (!strcmp(s, "rigger")) return K_trigger; - break; - case 'u': - if (!strcmp(s, "ser")) return K_user; - break; - case 'w': - if (!strcmp(s, "rite")) return K_write; - break; - } - return K_UNKNOWN; -} - -void parse_line_no_op(struct parse_state *state, int nargs, char **args) -{ -} - -int next_token(struct parse_state *state) -{ - char *x = state->ptr; - char *s; - - if (state->nexttoken) { - int t = state->nexttoken; - state->nexttoken = 0; - return t; - } - - for (;;) { - switch (*x) { - case 0: - state->ptr = x; - return T_EOF; - case '\n': - state->line++; - x++; - state->ptr = x; - return T_NEWLINE; - case ' ': - case '\t': - case '\r': - x++; - continue; - case '#': - while (*x && (*x != '\n')) x++; - state->line++; - state->ptr = x; - return T_NEWLINE; - default: - goto text; - } - } - -textdone: - state->ptr = x; - *s = 0; - return T_TEXT; -text: - state->text = s = x; -textresume: - for (;;) { - switch (*x) { - case 0: - goto textdone; - case ' ': - case '\t': - case '\r': - x++; - goto textdone; - case '\n': - state->nexttoken = T_NEWLINE; - x++; - goto textdone; - case '"': - x++; - for (;;) { - switch (*x) { - case 0: - /* unterminated quoted thing */ - state->ptr = x; - return T_EOF; - case '"': - x++; - goto textresume; - default: - *s++ = *x++; - } - } - break; - case '\\': - x++; - switch (*x) { - case 0: - goto textdone; - case 'n': - *s++ = '\n'; - break; - case 'r': - *s++ = '\r'; - break; - case 't': - *s++ = '\t'; - break; - case '\\': - *s++ = '\\'; - break; - case '\r': - /* \ <cr> <lf> -> line continuation */ - if (x[1] != '\n') { - x++; - continue; - } - case '\n': - /* \ <lf> -> line continuation */ - state->line++; - x++; - /* eat any extra whitespace */ - while((*x == ' ') || (*x == '\t')) x++; - continue; - default: - /* unknown escape -- just copy */ - *s++ = *x++; - } - continue; - default: - *s++ = *x++; - } - } - return T_EOF; -} - -void parse_line(int nargs, char **args) -{ - int n; - int id = lookup_keyword(args[0]); - printf("%s(%d)", args[0], id); - for (n = 1; n < nargs; n++) { - printf(" '%s'", args[n]); - } - printf("\n"); -} - -void parse_new_section(struct parse_state *state, int kw, - int nargs, char **args) -{ - printf("[ %s %s ]\n", args[0], - nargs > 1 ? args[1] : ""); - switch(kw) { - case K_service: - state->context = parse_service(state, nargs, args); - if (state->context) { - state->parse_line = parse_line_service; - return; - } - break; - case K_on: - state->context = parse_action(state, nargs, args); - if (state->context) { - state->parse_line = parse_line_action; - return; - } - break; - } - state->parse_line = parse_line_no_op; -} - -static void parse_config(const char *fn, char *s) -{ - struct parse_state state; - char *args[MAXARGS]; - int nargs; - - nargs = 0; - state.filename = fn; - state.line = 1; - state.ptr = s; - state.nexttoken = 0; - state.parse_line = parse_line_no_op; - for (;;) { - switch (next_token(&state)) { - case T_EOF: - state.parse_line(&state, 0, 0); - return; - case T_NEWLINE: - if (nargs) { - int kw = lookup_keyword(args[0]); - if (kw_is(kw, SECTION)) { - state.parse_line(&state, 0, 0); - parse_new_section(&state, kw, nargs, args); - } else { - state.parse_line(&state, nargs, args); - } - nargs = 0; - } - break; - case T_TEXT: - if (nargs < MAXARGS) { - args[nargs++] = state.text; - } - break; - } - } -} - -int parse_config_file(const char *fn) -{ - char *data; - data = read_file(fn, 0); - if (!data) return -1; - - parse_config(fn, data); - DUMP(); - return 0; -} - -static int valid_name(const char *name) -{ - if (strlen(name) > 16) { - return 0; - } - while (*name) { - if (!isalnum(*name) && (*name != '_') && (*name != '-')) { - return 0; - } - name++; - } - return 1; -} - -struct service *service_find_by_name(const char *name) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - if (!strcmp(svc->name, name)) { - return svc; - } - } - return 0; -} - -struct service *service_find_by_pid(pid_t pid) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - if (svc->pid == pid) { - return svc; - } - } - return 0; -} - -struct service *service_find_by_keychord(int keychord_id) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - if (svc->keychord_id == keychord_id) { - return svc; - } - } - return 0; -} - -void service_for_each(void (*func)(struct service *svc)) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - func(svc); - } -} - -void service_for_each_class(const char *classname, - void (*func)(struct service *svc)) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - if (!strcmp(svc->classname, classname)) { - func(svc); - } - } -} - -void service_for_each_flags(unsigned matchflags, - void (*func)(struct service *svc)) -{ - struct listnode *node; - struct service *svc; - list_for_each(node, &service_list) { - svc = node_to_item(node, struct service, slist); - if (svc->flags & matchflags) { - func(svc); - } - } -} - -void action_for_each_trigger(const char *trigger, - void (*func)(struct action *act)) -{ - struct listnode *node; - struct action *act; - list_for_each(node, &action_list) { - act = node_to_item(node, struct action, alist); - if (!strcmp(act->name, trigger)) { - func(act); - } - } -} - -void queue_property_triggers(const char *name, const char *value) -{ - struct listnode *node; - struct action *act; - list_for_each(node, &action_list) { - act = node_to_item(node, struct action, alist); - if (!strncmp(act->name, "property:", strlen("property:"))) { - const char *test = act->name + strlen("property:"); - int name_length = strlen(name); - - if (!strncmp(name, test, name_length) && - test[name_length] == '=' && - !strcmp(test + name_length + 1, value)) { - action_add_queue_tail(act); - } - } - } -} - -void queue_all_property_triggers() -{ - struct listnode *node; - struct action *act; - list_for_each(node, &action_list) { - act = node_to_item(node, struct action, alist); - if (!strncmp(act->name, "property:", strlen("property:"))) { - /* parse property name and value - syntax is property:<name>=<value> */ - const char* name = act->name + strlen("property:"); - const char* equals = strchr(name, '='); - if (equals) { - char* prop_name[PROP_NAME_MAX + 1]; - const char* value; - int length = equals - name; - if (length > PROP_NAME_MAX) { - ERROR("property name too long in trigger %s", act->name); - } else { - memcpy(prop_name, name, length); - prop_name[length] = 0; - - /* does the property exist, and match the trigger value? */ - value = property_get((const char *)&prop_name[0]); - if (value && !strcmp(equals + 1, value)) { - action_add_queue_tail(act); - } - } - } - } - } -} - -void action_add_queue_tail(struct action *act) -{ - list_add_tail(&action_queue, &act->qlist); -} - -struct action *action_remove_queue_head(void) -{ - if (list_empty(&action_queue)) { - return 0; - } else { - struct listnode *node = list_head(&action_queue); - struct action *act = node_to_item(node, struct action, qlist); - list_remove(node); - return act; - } -} - -static void *parse_service(struct parse_state *state, int nargs, char **args) -{ - struct service *svc; - if (nargs < 3) { - parse_error(state, "services must have a name and a program\n"); - return 0; - } - if (!valid_name(args[1])) { - parse_error(state, "invalid service name '%s'\n", args[1]); - return 0; - } - - svc = service_find_by_name(args[1]); - if (svc) { - parse_error(state, "ignored duplicate definition of service '%s'\n", args[1]); - return 0; - } - - nargs -= 2; - svc = calloc(1, sizeof(*svc) + sizeof(char*) * nargs); - if (!svc) { - parse_error(state, "out of memory\n"); - return 0; - } - svc->name = args[1]; - svc->classname = "default"; - memcpy(svc->args, args + 2, sizeof(char*) * nargs); - svc->args[nargs] = 0; - svc->nargs = nargs; - svc->onrestart.name = "onrestart"; - list_init(&svc->onrestart.commands); - list_add_tail(&service_list, &svc->slist); - return svc; -} - -static void parse_line_service(struct parse_state *state, int nargs, char **args) -{ - struct service *svc = state->context; - struct command *cmd; - int i, kw, kw_nargs; - - if (nargs == 0) { - return; - } - - kw = lookup_keyword(args[0]); - switch (kw) { - case K_capability: - break; - case K_class: - if (nargs != 2) { - parse_error(state, "class option requires a classname\n"); - } else { - svc->classname = args[1]; - } - break; - case K_console: - svc->flags |= SVC_CONSOLE; - break; - case K_disabled: - svc->flags |= SVC_DISABLED; - break; - case K_group: - if (nargs < 2) { - parse_error(state, "group option requires a group id\n"); - } else if (nargs > NR_SVC_SUPP_GIDS + 2) { - parse_error(state, "group option accepts at most %d supp. groups\n", - NR_SVC_SUPP_GIDS); - } else { - int n; - svc->gid = decode_uid(args[1]); - for (n = 2; n < nargs; n++) { - svc->supp_gids[n-2] = decode_uid(args[n]); - } - svc->nr_supp_gids = n - 2; - } - break; - case K_keycodes: - if (nargs < 2) { - parse_error(state, "keycodes option requires atleast one keycode\n"); - } else { - svc->keycodes = malloc((nargs - 1) * sizeof(svc->keycodes[0])); - if (!svc->keycodes) { - parse_error(state, "could not allocate keycodes\n"); - } else { - svc->nkeycodes = nargs - 1; - for (i = 1; i < nargs; i++) { - svc->keycodes[i - 1] = atoi(args[i]); - } - } - } - break; - case K_oneshot: - svc->flags |= SVC_ONESHOT; - break; - case K_onrestart: - nargs--; - args++; - kw = lookup_keyword(args[0]); - if (!kw_is(kw, COMMAND)) { - parse_error(state, "invalid command '%s'\n", args[0]); - break; - } - kw_nargs = kw_nargs(kw); - if (nargs < kw_nargs) { - parse_error(state, "%s requires %d %s\n", args[0], kw_nargs - 1, - kw_nargs > 2 ? "arguments" : "argument"); - break; - } - - cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs); - cmd->func = kw_func(kw); - cmd->nargs = nargs; - memcpy(cmd->args, args, sizeof(char*) * nargs); - list_add_tail(&svc->onrestart.commands, &cmd->clist); - break; - case K_critical: - svc->flags |= SVC_CRITICAL; - break; - case K_setenv: { /* name value */ - struct svcenvinfo *ei; - if (nargs < 2) { - parse_error(state, "setenv option requires name and value arguments\n"); - break; - } - ei = calloc(1, sizeof(*ei)); - if (!ei) { - parse_error(state, "out of memory\n"); - break; - } - ei->name = args[1]; - ei->value = args[2]; - ei->next = svc->envvars; - svc->envvars = ei; - break; - } - case K_socket: {/* name type perm [ uid gid ] */ - struct socketinfo *si; - if (nargs < 4) { - parse_error(state, "socket option requires name, type, perm arguments\n"); - break; - } - if (strcmp(args[2],"dgram") && strcmp(args[2],"stream")) { - parse_error(state, "socket type must be 'dgram' or 'stream'\n"); - break; - } - si = calloc(1, sizeof(*si)); - if (!si) { - parse_error(state, "out of memory\n"); - break; - } - si->name = args[1]; - si->type = args[2]; - si->perm = strtoul(args[3], 0, 8); - if (nargs > 4) - si->uid = decode_uid(args[4]); - if (nargs > 5) - si->gid = decode_uid(args[5]); - si->next = svc->sockets; - svc->sockets = si; - break; - } - case K_user: - if (nargs != 2) { - parse_error(state, "user option requires a user id\n"); - } else { - svc->uid = decode_uid(args[1]); - } - break; - default: - parse_error(state, "invalid option '%s'\n", args[0]); - } -} - -static void *parse_action(struct parse_state *state, int nargs, char **args) -{ - struct action *act; - if (nargs < 2) { - parse_error(state, "actions must have a trigger\n"); - return 0; - } - if (nargs > 2) { - parse_error(state, "actions may not have extra parameters\n"); - return 0; - } - act = calloc(1, sizeof(*act)); - act->name = args[1]; - list_init(&act->commands); - list_add_tail(&action_list, &act->alist); - /* XXX add to hash */ - return act; -} - -static void parse_line_action(struct parse_state* state, int nargs, char **args) -{ - struct command *cmd; - struct action *act = state->context; - int (*func)(int nargs, char **args); - int kw, n; - - if (nargs == 0) { - return; - } - - kw = lookup_keyword(args[0]); - if (!kw_is(kw, COMMAND)) { - parse_error(state, "invalid command '%s'\n", args[0]); - return; - } - - n = kw_nargs(kw); - if (nargs < n) { - parse_error(state, "%s requires %d %s\n", args[0], n - 1, - n > 2 ? "arguments" : "argument"); - return; - } - cmd = malloc(sizeof(*cmd) + sizeof(char*) * nargs); - cmd->func = kw_func(kw); - cmd->nargs = nargs; - memcpy(cmd->args, args, sizeof(char*) * nargs); - list_add_tail(&act->commands, &cmd->clist); -} diff --git a/init/property_service.c b/init/property_service.c deleted file mode 100644 index 7a6416b5e925628ac1eda08566e4f4574de04da3..0000000000000000000000000000000000000000 --- a/init/property_service.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <ctype.h> -#include <fcntl.h> -#include <stdarg.h> -#include <dirent.h> -#include <limits.h> -#include <errno.h> - -#include <cutils/misc.h> -#include <cutils/sockets.h> -#include <cutils/ashmem.h> - -#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ -#include <sys/_system_properties.h> - -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <sys/mman.h> -#include <sys/atomics.h> -#include <private/android_filesystem_config.h> - -#include "property_service.h" -#include "init.h" - -#define PERSISTENT_PROPERTY_DIR "/data/property" - -static int persistent_properties_loaded = 0; - -/* White list of permissions for setting property services. */ -struct { - const char *prefix; - unsigned int uid; -} property_perms[] = { - { "net.rmnet0.", AID_RADIO }, - { "net.gprs.", AID_RADIO }, - { "ril.", AID_RADIO }, - { "gsm.", AID_RADIO }, - { "net.dns", AID_RADIO }, - { "net.", AID_SYSTEM }, - { "dev.", AID_SYSTEM }, - { "runtime.", AID_SYSTEM }, - { "hw.", AID_SYSTEM }, - { "sys.", AID_SYSTEM }, - { "service.", AID_SYSTEM }, - { "wlan.", AID_SYSTEM }, - { "dhcp.", AID_SYSTEM }, - { "dhcp.", AID_DHCP }, - { "debug.", AID_SHELL }, - { "log.", AID_SHELL }, - { "persist.sys.", AID_SYSTEM }, - { "persist.service.", AID_SYSTEM }, - { NULL, 0 } -}; - -/* - * White list of UID that are allowed to start/stop services. - * Currently there are no user apps that require. - */ -struct { - const char *service; - unsigned int uid; -} control_perms[] = { - {NULL, 0 } -}; - -typedef struct { - void *data; - size_t size; - int fd; -} workspace; - -static int init_workspace(workspace *w, size_t size) -{ - void *data; - int fd; - - fd = ashmem_create_region("system_properties", size); - if(fd < 0) - return -1; - - data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); - if(data == MAP_FAILED) - goto out; - - /* allow the wolves we share with to do nothing but read */ - ashmem_set_prot_region(fd, PROT_READ); - - w->data = data; - w->size = size; - w->fd = fd; - - return 0; - -out: - close(fd); - return -1; -} - -/* (8 header words + 247 toc words) = 1020 bytes */ -/* 1024 bytes header and toc + 247 prop_infos @ 128 bytes = 32640 bytes */ - -#define PA_COUNT_MAX 247 -#define PA_INFO_START 1024 -#define PA_SIZE 32768 - -static workspace pa_workspace; -static prop_info *pa_info_array; - -extern prop_area *__system_property_area__; - -static int init_property_area(void) -{ - prop_area *pa; - - if(pa_info_array) - return -1; - - if(init_workspace(&pa_workspace, PA_SIZE)) - return -1; - - fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC); - - pa_info_array = (void*) (((char*) pa_workspace.data) + PA_INFO_START); - - pa = pa_workspace.data; - memset(pa, 0, PA_SIZE); - pa->magic = PROP_AREA_MAGIC; - pa->version = PROP_AREA_VERSION; - - /* plug into the lib property services */ - __system_property_area__ = pa; - - return 0; -} - -static void update_prop_info(prop_info *pi, const char *value, unsigned len) -{ - pi->serial = pi->serial | 1; - memcpy(pi->value, value, len + 1); - pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff); - __futex_wake(&pi->serial, INT32_MAX); -} - -static int property_write(prop_info *pi, const char *value) -{ - int valuelen = strlen(value); - if(valuelen >= PROP_VALUE_MAX) return -1; - update_prop_info(pi, value, valuelen); - return 0; -} - - -/* - * Checks permissions for starting/stoping system services. - * AID_SYSTEM and AID_ROOT are always allowed. - * - * Returns 1 if uid allowed, 0 otherwise. - */ -static int check_control_perms(const char *name, int uid) { - int i; - if (uid == AID_SYSTEM || uid == AID_ROOT) - return 1; - - /* Search the ACL */ - for (i = 0; control_perms[i].service; i++) { - if (strcmp(control_perms[i].service, name) == 0) { - if (control_perms[i].uid == uid) - return 1; - } - } - return 0; -} - -/* - * Checks permissions for setting system properties. - * Returns 1 if uid allowed, 0 otherwise. - */ -static int check_perms(const char *name, unsigned int uid) -{ - int i; - if (uid == 0) - return 1; - - if(!strncmp(name, "ro.", 3)) - name +=3; - - for (i = 0; property_perms[i].prefix; i++) { - int tmp; - if (strncmp(property_perms[i].prefix, name, - strlen(property_perms[i].prefix)) == 0) { - if (property_perms[i].uid == uid) { - return 1; - } - } - } - - return 0; -} - -const char* property_get(const char *name) -{ - prop_info *pi; - - if(strlen(name) >= PROP_NAME_MAX) return 0; - - pi = (prop_info*) __system_property_find(name); - - if(pi != 0) { - return pi->value; - } else { - return 0; - } -} - -static void write_peristent_property(const char *name, const char *value) -{ - const char *tempPath = PERSISTENT_PROPERTY_DIR "/.temp"; - char path[PATH_MAX]; - int fd, length; - - snprintf(path, sizeof(path), "%s/%s", PERSISTENT_PROPERTY_DIR, name); - - fd = open(tempPath, O_WRONLY|O_CREAT|O_TRUNC, 0600); - if (fd < 0) { - ERROR("Unable to write persistent property to temp file %s errno: %d\n", tempPath, errno); - return; - } - write(fd, value, strlen(value)); - close(fd); - - if (rename(tempPath, path)) { - unlink(tempPath); - ERROR("Unable to rename persistent property file %s to %s\n", tempPath, path); - } -} - -int property_set(const char *name, const char *value) -{ - prop_area *pa; - prop_info *pi; - - int namelen = strlen(name); - int valuelen = strlen(value); - - if(namelen >= PROP_NAME_MAX) return -1; - if(valuelen >= PROP_VALUE_MAX) return -1; - if(namelen < 1) return -1; - - pi = (prop_info*) __system_property_find(name); - - if(pi != 0) { - /* ro.* properties may NEVER be modified once set */ - if(!strncmp(name, "ro.", 3)) return -1; - - pa = __system_property_area__; - update_prop_info(pi, value, valuelen); - pa->serial++; - __futex_wake(&pa->serial, INT32_MAX); - } else { - pa = __system_property_area__; - if(pa->count == PA_COUNT_MAX) return -1; - - pi = pa_info_array + pa->count; - pi->serial = (valuelen << 24); - memcpy(pi->name, name, namelen + 1); - memcpy(pi->value, value, valuelen + 1); - - pa->toc[pa->count] = - (namelen << 24) | (((unsigned) pi) - ((unsigned) pa)); - - pa->count++; - pa->serial++; - __futex_wake(&pa->serial, INT32_MAX); - } - /* If name starts with "net." treat as a DNS property. */ - if (strncmp("net.", name, sizeof("net.") - 1) == 0) { - if (strcmp("net.change", name) == 0) { - return 0; - } - /* - * The 'net.change' property is a special property used track when any - * 'net.*' property name is updated. It is _ONLY_ updated here. Its value - * contains the last updated 'net.*' property. - */ - property_set("net.change", name); - } else if (persistent_properties_loaded && - strncmp("persist.", name, sizeof("persist.") - 1) == 0) { - /* - * Don't write properties to disk until after we have read all default properties - * to prevent them from being overwritten by default values. - */ - write_peristent_property(name, value); - } - property_changed(name, value); - return 0; -} - -static int property_list(void (*propfn)(const char *key, const char *value, void *cookie), - void *cookie) -{ - char name[PROP_NAME_MAX]; - char value[PROP_VALUE_MAX]; - const prop_info *pi; - unsigned n; - - for(n = 0; (pi = __system_property_find_nth(n)); n++) { - __system_property_read(pi, name, value); - propfn(name, value, cookie); - } - return 0; -} - -void handle_property_set_fd(int fd) -{ - prop_msg msg; - int s; - int r; - int res; - struct ucred cr; - struct sockaddr_un addr; - socklen_t addr_size = sizeof(addr); - socklen_t cr_size = sizeof(cr); - - if ((s = accept(fd, (struct sockaddr *) &addr, &addr_size)) < 0) { - return; - } - - /* Check socket options here */ - if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) { - close(s); - ERROR("Unable to recieve socket options\n"); - return; - } - - r = recv(s, &msg, sizeof(msg), 0); - close(s); - if(r != sizeof(prop_msg)) { - ERROR("sys_prop: mis-match msg size recieved: %d expected: %d\n", - r, sizeof(prop_msg)); - return; - } - - switch(msg.cmd) { - case PROP_MSG_SETPROP: - msg.name[PROP_NAME_MAX-1] = 0; - msg.value[PROP_VALUE_MAX-1] = 0; - - if(memcmp(msg.name,"ctl.",4) == 0) { - if (check_control_perms(msg.value, cr.uid)) { - handle_control_message((char*) msg.name + 4, (char*) msg.value); - } else { - ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n", - msg.name + 4, msg.value, cr.uid, cr.pid); - } - } else { - if (check_perms(msg.name, cr.uid)) { - property_set((char*) msg.name, (char*) msg.value); - } else { - ERROR("sys_prop: permission denied uid:%d name:%s\n", - cr.uid, msg.name); - } - } - break; - - default: - break; - } -} - -void get_property_workspace(int *fd, int *sz) -{ - *fd = pa_workspace.fd; - *sz = pa_workspace.size; -} - -static void load_properties(char *data) -{ - char *key, *value, *eol, *sol, *tmp; - - sol = data; - while((eol = strchr(sol, '\n'))) { - key = sol; - *eol++ = 0; - sol = eol; - - value = strchr(key, '='); - if(value == 0) continue; - *value++ = 0; - - while(isspace(*key)) key++; - if(*key == '#') continue; - tmp = value - 2; - while((tmp > key) && isspace(*tmp)) *tmp-- = 0; - - while(isspace(*value)) value++; - tmp = eol - 2; - while((tmp > value) && isspace(*tmp)) *tmp-- = 0; - - property_set(key, value); - } -} - -static void load_properties_from_file(const char *fn) -{ - char *data; - unsigned sz; - - data = read_file(fn, &sz); - - if(data != 0) { - load_properties(data); - free(data); - } -} - -static void load_persistent_properties() -{ - DIR* dir = opendir(PERSISTENT_PROPERTY_DIR); - struct dirent* entry; - char path[PATH_MAX]; - char value[PROP_VALUE_MAX]; - int fd, length; - - if (dir) { - while ((entry = readdir(dir)) != NULL) { - if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") || - strncmp("persist.", entry->d_name, sizeof("persist.") - 1)) - continue; -#if HAVE_DIRENT_D_TYPE - if (entry->d_type != DT_REG) - continue; -#endif - /* open the file and read the property value */ - snprintf(path, sizeof(path), "%s/%s", PERSISTENT_PROPERTY_DIR, entry->d_name); - fd = open(path, O_RDONLY); - if (fd >= 0) { - length = read(fd, value, sizeof(value) - 1); - if (length >= 0) { - value[length] = 0; - property_set(entry->d_name, value); - } else { - ERROR("Unable to read persistent property file %s errno: %d\n", path, errno); - } - close(fd); - } else { - ERROR("Unable to open persistent property file %s errno: %d\n", path, errno); - } - } - closedir(dir); - } else { - ERROR("Unable to open persistent property directory %s errno: %d\n", PERSISTENT_PROPERTY_DIR, errno); - } - - persistent_properties_loaded = 1; -} - -void property_init(void) -{ - init_property_area(); - load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT); -} - -int start_property_service(void) -{ - int fd; - - load_properties_from_file(PROP_PATH_SYSTEM_BUILD); - load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT); - load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE); - /* Read persistent properties after all default values have been loaded. */ - load_persistent_properties(); - - fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0); - if(fd < 0) return -1; - fcntl(fd, F_SETFD, FD_CLOEXEC); - fcntl(fd, F_SETFL, O_NONBLOCK); - - listen(fd, 8); - return fd; -} diff --git a/init/property_service.h b/init/property_service.h deleted file mode 100644 index d12f1f38bfaafcb07ea3ac87737b95bcdc310b12..0000000000000000000000000000000000000000 --- a/init/property_service.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _INIT_PROPERTY_H -#define _INIT_PROPERTY_H - -extern void handle_property_fd(int fd); -extern void handle_property_set_fd(int fd); -extern void property_init(void); -extern int start_property_service(void); -void get_property_workspace(int *fd, int *sz); -extern const char* property_get(const char *name); -extern int property_set(const char *name, const char *value); - -#endif /* _INIT_PROPERTY_H */ diff --git a/init/readme.txt b/init/readme.txt deleted file mode 100644 index 665090bad7dfdc93112f9fe13261095dcef5d3e4..0000000000000000000000000000000000000000 --- a/init/readme.txt +++ /dev/null @@ -1,293 +0,0 @@ - -Android Init Language ---------------------- - -The Android Init Language consists of four broad classes of statements, -which are Actions, Commands, Services, and Options. - -All of these are line-oriented, consisting of tokens separated by -whitespace. The c-style backslash escapes may be used to insert -whitespace into a token. Double quotes may also be used to prevent -whitespace from breaking text into multiple tokens. The backslash, -when it is the last character on a line, may be used for line-folding. - -Lines which start with a # (leading whitespace allowed) are comments. - -Actions and Services implicitly declare a new section. All commands -or options belong to the section most recently declared. Commands -or options before the first section are ignored. - -Actions and Services have unique names. If a second Action or Service -is declared with the same name as an existing one, it is ignored as -an error. (??? should we override instead) - - -Actions -------- -Actions are named sequences of commands. Actions have a trigger which -is used to determine when the action should occur. When an event -occurs which matches an action's trigger, that action is added to -the tail of a to-be-executed queue (unless it is already on the -queue). - -Each action in the queue is dequeued in sequence and each command in -that action is executed in sequence. Init handles other activities -(device creation/destruction, property setting, process restarting) -"between" the execution of the commands in activities. - -Actions take the form of: - -on <trigger> - <command> - <command> - <command> - - -Services --------- -Services are programs which init launches and (optionally) restarts -when they exit. Services take the form of: - -service <name> <pathname> [ <argument> ]* - <option> - <option> - ... - - -Options -------- -Options are modifiers to services. They affect how and when init -runs the service. - -critical - This is a device-critical service. If it exits more than four times in - four minutes, the device will reboot into recovery mode. - -disabled - This service will not automatically start with its class. - It must be explicitly started by name. - -setenv <name> <value> - Set the environment variable <name> to <value> in the launched process. - -socket <name> <type> <perm> [ <user> [ <group> ] ] - Create a unix domain socket named /dev/socket/<name> and pass - its fd to the launched process. <type> must be "dgram" or "stream". - User and group default to 0. - -user <username> - Change to username before exec'ing this service. - Currently defaults to root. (??? probably should default to nobody) - Currently, if your process requires linux capabilities then you cannot use - this command. You must instead request the capabilities in-process while - still root, and then drop to your desired uid. - -group <groupname> [ <groupname> ]* - Change to groupname before exec'ing this service. Additional - groupnames beyond the (required) first one are used to set the - supplemental groups of the process (via setgroups()). - Currently defaults to root. (??? probably should default to nobody) - -oneshot - Do not restart the service when it exits. - -class <name> - Specify a class name for the service. All services in a - named class may be started or stopped together. A service - is in the class "default" if one is not specified via the - class option. - -onrestart - Execute a Command (see below) when service restarts. - -Triggers --------- - Triggers are strings which can be used to match certain kinds - of events and used to cause an action to occur. - -boot - This is the first trigger that will occur when init starts - (after /init.conf is loaded) - -<name>=<value> - Triggers of this form occur when the property <name> is set - to the specific value <value>. - -device-added-<path> -device-removed-<path> - Triggers of these forms occur when a device node is added - or removed. - -service-exited-<name> - Triggers of this form occur when the specified service exits. - - -Commands --------- - -exec <path> [ <argument> ]* - Fork and execute a program (<path>). This will block until - the program completes execution. It is best to avoid exec - as unlike the builtin commands, it runs the risk of getting - init "stuck". (??? maybe there should be a timeout?) - -export <name> <value> - Set the environment variable <name> equal to <value> in the - global environment (which will be inherited by all processes - started after this command is executed) - -ifup <interface> - Bring the network interface <interface> online. - -import <filename> - Parse an init config file, extending the current configuration. - -hostname <name> - Set the host name. - -chmod <octal-mode> <path> - Change file access permissions. - -chown <owner> <group> <path> - Change file owner and group. - -class_start <serviceclass> - Start all services of the specified class if they are - not already running. - -class_stop <serviceclass> - Stop all services of the specified class if they are - currently running. - -domainname <name> - Set the domain name. - -insmod <path> - Install the module at <path> - -mkdir <path> [mode] [owner] [group] - Create a directory at <path>, optionally with the given mode, owner, and - group. If not provided, the directory is created with permissions 755 and - owned by the root user and root group. - -mount <type> <device> <dir> [ <mountoption> ]* - Attempt to mount the named device at the directory <dir> - <device> may be of the form mtd@name to specify a mtd block - device by name. - <mountoption>s include "ro", "rw", "remount", "noatime", ... - -setkey - TBD - -setprop <name> <value> - Set system property <name> to <value>. - -setrlimit <resource> <cur> <max> - Set the rlimit for a resource. - -start <service> - Start a service running if it is not already running. - -stop <service> - Stop a service from running if it is currently running. - -symlink <target> <path> - Create a symbolic link at <path> with the value <target> - -sysclktz <mins_west_of_gmt> - Set the system clock base (0 if system clock ticks in GMT) - -trigger <event> - Trigger an event. Used to queue an action from another - action. - -write <path> <string> [ <string> ]* - Open the file at <path> and write one or more strings - to it with write(2) - - -Properties ----------- -Init updates some system properties to provide some insight into -what it's doing: - -init.action - Equal to the name of the action currently being executed or "" if none - -init.command - Equal to the command being executed or "" if none. - -init.svc.<name> - State of a named service ("stopped", "running", "restarting") - - -Example init.conf ------------------ - -# not complete -- just providing some examples of usage -# -on boot - export PATH /sbin:/system/sbin:/system/bin - export LD_LIBRARY_PATH /system/lib - - mkdir /dev - mkdir /proc - mkdir /sys - - mount tmpfs tmpfs /dev - mkdir /dev/pts - mkdir /dev/socket - mount devpts devpts /dev/pts - mount proc proc /proc - mount sysfs sysfs /sys - - write /proc/cpu/alignment 4 - - ifup lo - - hostname localhost - domainname localhost - - mount yaffs2 mtd@system /system - mount yaffs2 mtd@userdata /data - - import /system/etc/init.conf - - class_start default - -service adbd /sbin/adbd - user adb - group adb - -service usbd /system/bin/usbd -r - user usbd - group usbd - socket usbd 666 - -service zygote /system/bin/app_process -Xzygote /system/bin --zygote - socket zygote 666 - -service runtime /system/bin/runtime - user system - group system - -on device-added-/dev/compass - start akmd - -on device-removed-/dev/compass - stop akmd - -service akmd /sbin/akmd - disabled - user akmd - group akmd - -Debugging notes ---------------- -By default, programs executed by init will drop stdout and stderr into -/dev/null. To help with debugging, you can execute your program via the -Andoird program logwrapper. This will redirect stdout/stderr into the -Android logging system (accessed via logcat). - -For example -service akmd /system/bin/logwrapper /sbin/akmd diff --git a/init/util.c b/init/util.c deleted file mode 100644 index 0b7667dae8de1463a210467496a6e5dc425dfa2e..0000000000000000000000000000000000000000 --- a/init/util.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <ctype.h> -#include <errno.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> - -/* for ANDROID_SOCKET_* */ -#include <cutils/sockets.h> - -#include <private/android_filesystem_config.h> - -#include "init.h" - -static int log_fd = -1; -/* Inital log level before init.rc is parsed and this this is reset. */ -static int log_level = LOG_DEFAULT_LEVEL; - - -void log_set_level(int level) { - log_level = level; -} - -void log_init(void) -{ - static const char *name = "/dev/__kmsg__"; - if (mknod(name, S_IFCHR | 0600, (1 << 8) | 11) == 0) { - log_fd = open(name, O_WRONLY); - fcntl(log_fd, F_SETFD, FD_CLOEXEC); - unlink(name); - } -} - -#define LOG_BUF_MAX 512 - -void log_write(int level, const char *fmt, ...) -{ - char buf[LOG_BUF_MAX]; - va_list ap; - - if (level > log_level) return; - if (log_fd < 0) return; - - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_MAX, fmt, ap); - buf[LOG_BUF_MAX - 1] = 0; - va_end(ap); - write(log_fd, buf, strlen(buf)); -} - -/* - * android_name_to_id - returns the integer uid/gid associated with the given - * name, or -1U on error. - */ -static unsigned int android_name_to_id(const char *name) -{ - struct android_id_info *info = android_ids; - unsigned int n; - - for (n = 0; n < android_id_count; n++) { - if (!strcmp(info[n].name, name)) - return info[n].aid; - } - - return -1U; -} - -/* - * decode_uid - decodes and returns the given string, which can be either the - * numeric or name representation, into the integer uid or gid. Returns -1U on - * error. - */ -unsigned int decode_uid(const char *s) -{ - unsigned int v; - - if (!s || *s == '\0') - return -1U; - if (isalpha(s[0])) - return android_name_to_id(s); - - errno = 0; - v = (unsigned int) strtoul(s, 0, 0); - if (errno) - return -1U; - return v; -} - -/* - * create_socket - creates a Unix domain socket in ANDROID_SOCKET_DIR - * ("/dev/socket") as dictated in init.rc. This socket is inherited by the - * daemon. We communicate the file descriptor's value via the environment - * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo"). - */ -int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid) -{ - struct sockaddr_un addr; - int fd, ret; - - fd = socket(PF_UNIX, type, 0); - if (fd < 0) { - ERROR("Failed to open socket '%s': %s\n", name, strerror(errno)); - return -1; - } - - memset(&addr, 0 , sizeof(addr)); - addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", - name); - - ret = unlink(addr.sun_path); - if (ret != 0 && errno != ENOENT) { - ERROR("Failed to unlink old socket '%s': %s\n", name, strerror(errno)); - goto out_close; - } - - ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr)); - if (ret) { - ERROR("Failed to bind socket '%s': %s\n", name, strerror(errno)); - goto out_unlink; - } - - chown(addr.sun_path, uid, gid); - chmod(addr.sun_path, perm); - - INFO("Created socket '%s' with mode '%o', user '%d', group '%d'\n", - addr.sun_path, perm, uid, gid); - - return fd; - -out_unlink: - unlink(addr.sun_path); -out_close: - close(fd); - return -1; -} - -/* reads a file, making sure it is terminated with \n \0 */ -void *read_file(const char *fn, unsigned *_sz) -{ - char *data; - int sz; - int fd; - - data = 0; - fd = open(fn, O_RDONLY); - if(fd < 0) return 0; - - sz = lseek(fd, 0, SEEK_END); - if(sz < 0) goto oops; - - if(lseek(fd, 0, SEEK_SET) != 0) goto oops; - - data = (char*) malloc(sz + 2); - if(data == 0) goto oops; - - if(read(fd, data, sz) != sz) goto oops; - close(fd); - data[sz] = '\n'; - data[sz+1] = 0; - if(_sz) *_sz = sz; - return data; - -oops: - close(fd); - if(data != 0) free(data); - return 0; -} - -void list_init(struct listnode *node) -{ - node->next = node; - node->prev = node; -} - -void list_add_tail(struct listnode *head, struct listnode *item) -{ - item->next = head; - item->prev = head->prev; - head->prev->next = item; - head->prev = item; -} - -void list_remove(struct listnode *item) -{ - item->next->prev = item->prev; - item->prev->next = item->next; -} - diff --git a/libctest/Android.mk b/libctest/Android.mk deleted file mode 100644 index 815fabbf6a8c4b63f6d12428bfafe251987d0d51..0000000000000000000000000000000000000000 --- a/libctest/Android.mk +++ /dev/null @@ -1,7 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE:= libctest -LOCAL_SRC_FILES := ctest.c - -include $(BUILD_SHARED_LIBRARY) diff --git a/libctest/ctest.c b/libctest/ctest.c deleted file mode 100644 index ee6331fa04a6707ad8ced0c03d00af5e19f37a58..0000000000000000000000000000000000000000 --- a/libctest/ctest.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> -#include <ctest/ctest.h> - -#define MAX_TESTS 255 - -/** Semi-random number used to identify assertion errors. */ -#define ASSERTION_ERROR 42 - -typedef void TestCase(); - -/** A suite of tests. */ -typedef struct { - int size; - const char* testNames[MAX_TESTS]; - TestCase* tests[MAX_TESTS]; - int currentTest; - FILE* out; -} TestSuite; - -/** Gets the test suite. Creates it if necessary. */ -static TestSuite* getTestSuite() { - static TestSuite* suite = NULL; - - if (suite != NULL) { - return suite; - } - - suite = calloc(1, sizeof(TestSuite)); - assert(suite != NULL); - - suite->out = tmpfile(); - assert(suite->out != NULL); - - return suite; -} - -void addNamedTest(const char* name, TestCase* test) { - TestSuite* testSuite = getTestSuite(); - assert(testSuite->size <= MAX_TESTS); - - int index = testSuite->size; - testSuite->testNames[index] = name; - testSuite->tests[index] = test; - - testSuite->size++; -} - -/** Prints failures to stderr. */ -static void printFailures(int failures) { - TestSuite* suite = getTestSuite(); - - fprintf(stderr, "FAILURE! %d of %d tests failed. Failures:\n", - failures, suite->size); - - // Copy test output to stdout. - rewind(suite->out); - char buffer[512]; - size_t read; - while ((read = fread(buffer, sizeof(char), 512, suite->out)) > 0) { - // TODO: Make sure we actually wrote 'read' bytes. - fwrite(buffer, sizeof(char), read, stderr); - } -} - -/** Runs a single test case. */ -static int runCurrentTest() { - TestSuite* suite = getTestSuite(); - - pid_t pid = fork(); - if (pid == 0) { - // Child process. Runs test case. - suite->tests[suite->currentTest](); - - // Exit successfully. - exit(0); - } else if (pid < 0) { - fprintf(stderr, "Fork failed."); - exit(1); - } else { - // Parent process. Wait for child. - int status; - waitpid(pid, &status, 0); - - if (!WIFEXITED(status)) { - return -1; - } - - return WEXITSTATUS(status); - } -} - -void runTests() { - TestSuite* suite = getTestSuite(); - - int failures = 0; - for (suite->currentTest = 0; suite->currentTest < suite->size; - suite->currentTest++) { - // Flush stdout before forking. - fflush(stdout); - - int result = runCurrentTest(); - - if (result != 0) { - printf("X"); - - failures++; - - // Handle errors other than assertions. - if (result != ASSERTION_ERROR) { - // TODO: Report file name. - fprintf(suite->out, "Process failed: [%s] status: %d\n", - suite->testNames[suite->currentTest], result); - fflush(suite->out); - } - } else { - printf("."); - } - } - - printf("\n"); - - if (failures > 0) { - printFailures(failures); - } else { - printf("SUCCESS! %d tests ran successfully.\n", suite->size); - } -} - -void assertTrueWithSource(int value, const char* file, int line, char* message) { - if (!value) { - TestSuite* suite = getTestSuite(); - - fprintf(suite->out, "Assertion failed: [%s:%d] %s: %s\n", file, line, - suite->testNames[suite->currentTest], message); - fflush(suite->out); - - // Exit the process for this test case. - exit(ASSERTION_ERROR); - } -} diff --git a/libcutils/Android.mk b/libcutils/Android.mk deleted file mode 100644 index a43f7e3e476b5ecb6648c5b9b93b1d8f851bcf55..0000000000000000000000000000000000000000 --- a/libcutils/Android.mk +++ /dev/null @@ -1,113 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(my-dir) -include $(CLEAR_VARS) - -commonSources := \ - array.c \ - hashmap.c \ - atomic.c \ - buffer.c \ - socket_inaddr_any_server.c \ - socket_local_client.c \ - socket_local_server.c \ - socket_loopback_client.c \ - socket_loopback_server.c \ - socket_network_client.c \ - config_utils.c \ - cpu_info.c \ - load_file.c \ - strdup16to8.c \ - strdup8to16.c \ - record_stream.c \ - process_name.c \ - properties.c \ - threads.c - -# some files must not be compiled when building against Mingw -# they correspond to features not used by our host development tools -# which are also hard or even impossible to port to native Win32 -WITH_MINGW := -ifeq ($(HOST_OS),windows) - ifeq ($(strip $(USE_CYGWIN)),) - WITH_MINGW := 1 - endif -endif -# USE_MINGW is defined when we build against Mingw on Linux -ifneq ($(strip $(USE_MINGW)),) - WITH_MINGW := 1 -endif - -ifeq ($(WITH_MINGW),1) - commonSources += \ - uio.c -else - commonSources += \ - mspace.c \ - selector.c \ - fdevent.c \ - tztime.c \ - tzstrftime.c \ - adb_networking.c \ - zygote.c -endif - - -# Static library for host -# ======================================================== -LOCAL_MODULE := libcutils -LOCAL_SRC_FILES := $(commonSources) ashmem-host.c -LOCAL_LDLIBS := -lpthread -LOCAL_STATIC_LIBRARIES := liblog -include $(BUILD_HOST_STATIC_LIBRARY) - - -ifeq ($(TARGET_SIMULATOR),true) - -# Shared library for simulator -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := libcutils -LOCAL_SRC_FILES := $(commonSources) memory.c dlmalloc_stubs.c ashmem-host.c -LOCAL_LDLIBS := -lpthread -LOCAL_SHARED_LIBRARIES := liblog -include $(BUILD_SHARED_LIBRARY) - -else #!sim - -# Shared and static library for target -# ======================================================== -include $(CLEAR_VARS) -LOCAL_MODULE := libcutils -LOCAL_SRC_FILES := $(commonSources) ashmem-dev.c mq.c - -ifeq ($(TARGET_ARCH),arm) -LOCAL_SRC_FILES += memset32.S atomic-android-arm.S -else # !arm -LOCAL_SRC_FILES += memory.c -endif # !arm - -LOCAL_C_INCLUDES := $(KERNEL_HEADERS) -LOCAL_STATIC_LIBRARIES := liblog -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) -LOCAL_MODULE := libcutils -LOCAL_WHOLE_STATIC_LIBRARIES := libcutils -LOCAL_SHARED_LIBRARIES := liblog -include $(BUILD_SHARED_LIBRARY) - -endif #!sim diff --git a/libcutils/MODULE_LICENSE_APACHE2 b/libcutils/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libcutils/NOTICE b/libcutils/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/libcutils/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/libcutils/adb_networking.c b/libcutils/adb_networking.c deleted file mode 100644 index d819d44c8de97997efd6c7ab1a9a4de8c53a5469..0000000000000000000000000000000000000000 --- a/libcutils/adb_networking.c +++ /dev/null @@ -1,172 +0,0 @@ -/* libs/utils/adb_networking.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define ADB_PORT 5037 - -#define _GNU_SOURCE /* for asprintf */ -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <errno.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include <string.h> - -#include <cutils/adb_networking.h> -#include <cutils/sockets.h> -#include <cutils/properties.h> - -#define ADB_RESPONSE_SIZE 4 - -/** - * Unfortunately, java.net.Socket wants to create it's filedescriptor early - * So, this function takes an fd that must be an unconnected - * PF_LOCAL SOCK_STREAM - */ -int adb_networking_connect_fd(int fd, struct sockaddr_in *p_address) -{ - struct sockaddr_in local_addr; - socklen_t alen; - char *cmd; - char buf[ADB_RESPONSE_SIZE + 1]; - ssize_t count_read; - int ret; - int err; - /* for impl of inet_ntoa below*/ - union { - uint8_t b[4]; - uint32_t l; - } a; - - /* First, connect to adb */ - - memset(&local_addr, 0, sizeof(local_addr)); - local_addr.sin_family = AF_INET; - local_addr.sin_port = htons(ADB_PORT); - local_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - do { - err = connect(fd, (struct sockaddr *) &local_addr, sizeof(local_addr)); - } while (err < 0 && errno == EINTR); - - if (err < 0) { - return -1; - } - - a.l = p_address->sin_addr.s_addr; - - // compose the command - asprintf(&cmd, "tcp:%u:%u.%u.%u.%u", - (unsigned int)ntohs(p_address->sin_port), - a.b[0],a.b[1],a.b[2],a.b[3]); - - // buf is now the ascii hex length of cmd - snprintf(buf, sizeof(buf), "%04X", strlen(cmd)); - - // write the 4-byte length - do { - err = write(fd, buf, 4); - } while (err < 0 && errno == EINTR); - - // write the command - do { - err = write(fd, cmd, strlen(cmd)); - } while (err < 0 && errno == EINTR); - - // read the result - do { - count_read = read(fd, buf, sizeof(buf) - 1); - } while (count_read < 0 && errno != EINTR); - - if (count_read == ADB_RESPONSE_SIZE - && 0 == strncmp(buf, "OKAY", ADB_RESPONSE_SIZE)) { - ret = 0; - } else { - /* what errno here? <shrug? */ - errno = ENETUNREACH; - ret = -1; - } - - free(cmd); - - return ret; -} - -/** - * Fills in *p_out_addr and returns 0 on success - * Memset's *p_out_addr and returns -1 on fail - */ - -int adb_networking_gethostbyname(const char *name, struct in_addr *p_out_addr) -{ - int fd; - char *cmd = NULL; - char buf[ADB_RESPONSE_SIZE + 1]; - int err; - ssize_t count_read; - - fd = socket_loopback_client(ADB_PORT, SOCK_STREAM); - - if (fd < 0) { - return -1; - } - - // compose the command - asprintf(&cmd, "dns:%s", name); - - // buf is now the ascii hex length of cmd - snprintf(buf, sizeof(buf), "%04X", strlen(cmd)); - - // write the 4-byte length - do { - err = write(fd, buf, 4); - } while (err < 0 && errno == EINTR); - - // write the command - do { - err = write(fd, cmd, strlen(cmd)); - } while (err < 0 && errno == EINTR); - - // read the result - do { - count_read = read(fd, buf, ADB_RESPONSE_SIZE); - } while (count_read < 0 && errno != EINTR); - - if (count_read != ADB_RESPONSE_SIZE - || 0 != strncmp(buf, "OKAY", ADB_RESPONSE_SIZE)) { - goto error; - } - - // read the actual IP address - do { - count_read = read(fd, &(p_out_addr->s_addr), sizeof(p_out_addr->s_addr)); - } while (count_read < 0 && errno != EINTR); - - if (count_read != 4) { - goto error; - } - - free(cmd); - close(fd); - return 0; -error: - free(cmd); - close(fd); - memset(p_out_addr, 0, sizeof(struct in_addr)); - return -1; -} - diff --git a/libcutils/array.c b/libcutils/array.c deleted file mode 100644 index ff2c8ff12c0d3a52ea670aaf7b88c3e65ccf1974..0000000000000000000000000000000000000000 --- a/libcutils/array.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/array.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#define INITIAL_CAPACITY (4) - -struct Array { - void** contents; - int size; - int capacity; -}; - -Array* arrayCreate() { - return calloc(1, sizeof(struct Array)); -} - -void arrayFree(Array* array) { - assert(array != NULL); - - // Free internal array. - free(array->contents); - - // Free the Array itself. - free(array); -} - -/** Returns 0 if successful, < 0 otherwise.. */ -static int ensureCapacity(Array* array, int capacity) { - int oldCapacity = array->capacity; - if (capacity > oldCapacity) { - int newCapacity = (oldCapacity == 0) ? INITIAL_CAPACITY : oldCapacity * 2; - - // Keep doubling capacity until we surpass necessary capacity. - while (newCapacity < capacity) { - newCapacity *= 2; - } - - void** newContents; - if (array->contents == NULL) { - // Allocate new array. - newContents = malloc(newCapacity * sizeof(void*)); - if (newContents == NULL) { - return -1; - } - } else { - // Expand existing array. - newContents = realloc(array->contents, sizeof(void*) * newCapacity); - if (newContents == NULL) { - return -1; - } - } - - array->capacity = newCapacity; - array->contents = newContents; - } - - return 0; -} - -int arrayAdd(Array* array, void* pointer) { - assert(array != NULL); - int size = array->size; - int result = ensureCapacity(array, size + 1); - if (result < 0) { - return result; - } - array->contents[size] = pointer; - array->size++; - return 0; -} - -static inline void checkBounds(Array* array, int index) { - assert(array != NULL); - assert(index < array->size); - assert(index >= 0); -} - -void* arrayGet(Array* array, int index) { - checkBounds(array, index); - return array->contents[index]; -} - -void* arrayRemove(Array* array, int index) { - checkBounds(array, index); - - void* pointer = array->contents[index]; - - int newSize = array->size - 1; - - // Shift entries left. - if (index != newSize) { - memmove(array->contents + index, array->contents + index + 1, - (sizeof(void*)) * (newSize - index)); - } - - array->size = newSize; - - return pointer; -} - -void* arraySet(Array* array, int index, void* pointer) { - checkBounds(array, index); - void* old = array->contents[index]; - array->contents[index] = pointer; - return old; -} - -int arraySetSize(Array* array, int newSize) { - assert(array != NULL); - assert(newSize >= 0); - - int oldSize = array->size; - - if (newSize > oldSize) { - // Expand. - int result = ensureCapacity(array, newSize); - if (result < 0) { - return result; - } - - // Zero out new entries. - memset(array->contents + sizeof(void*) * oldSize, 0, - sizeof(void*) * (newSize - oldSize)); - } - - array->size = newSize; - - return 0; -} - -int arraySize(Array* array) { - assert(array != NULL); - return array->size; -} - -const void** arrayUnwrap(Array* array) { - return array->contents; -} diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.c deleted file mode 100644 index 5e158af71b180f81bca633993ac43f1170d6448e..0000000000000000000000000000000000000000 --- a/libcutils/ashmem-dev.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Implementation of the user-space ashmem API for devices, which have our - * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version, - * used by the simulator. - */ - -#include <unistd.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <fcntl.h> - -#include <linux/ashmem.h> -#include <cutils/ashmem.h> - -#define ASHMEM_DEVICE "/dev/ashmem" - -/* - * ashmem_create_region - creates a new ashmem region and returns the file - * descriptor, or <0 on error - * - * `name' is an optional label to give the region (visible in /proc/pid/maps) - * `size' is the size of the region, in page-aligned bytes - */ -int ashmem_create_region(const char *name, size_t size) -{ - int fd, ret; - - fd = open(ASHMEM_DEVICE, O_RDWR); - if (fd < 0) - return fd; - - if (name) { - char buf[ASHMEM_NAME_LEN]; - - strlcpy(buf, name, sizeof(buf)); - ret = ioctl(fd, ASHMEM_SET_NAME, buf); - if (ret < 0) - goto error; - } - - ret = ioctl(fd, ASHMEM_SET_SIZE, size); - if (ret < 0) - goto error; - - return fd; - -error: - close(fd); - return ret; -} - -int ashmem_set_prot_region(int fd, int prot) -{ - return ioctl(fd, ASHMEM_SET_PROT_MASK, prot); -} - -int ashmem_pin_region(int fd, size_t offset, size_t len) -{ - struct ashmem_pin pin = { offset, len }; - return ioctl(fd, ASHMEM_PIN, &pin); -} - -int ashmem_unpin_region(int fd, size_t offset, size_t len) -{ - struct ashmem_pin pin = { offset, len }; - return ioctl(fd, ASHMEM_UNPIN, &pin); -} diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.c deleted file mode 100644 index dbb52bc476182d51eb0b39f579a4d52b2d63610b..0000000000000000000000000000000000000000 --- a/libcutils/ashmem-host.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Implementation of the user-space ashmem API for the simulator, which lacks - * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version. - */ - -#include <unistd.h> -#include <string.h> -#include <stdlib.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <errno.h> -#include <time.h> -#include <limits.h> - -#include <cutils/ashmem.h> - -int ashmem_create_region(const char *ignored, size_t size) -{ - static const char txt[] = "abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - char name[64]; - unsigned int retries = 0; - pid_t pid = getpid(); - int fd; - - srand(time(NULL) + pid); - -retry: - /* not beautiful, its just wolf-like loop unrolling */ - snprintf(name, sizeof(name), "/tmp/android-ashmem-%d-%c%c%c%c%c%c%c%c", - pid, - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))], - txt[(int) ((sizeof(txt) - 1) * (rand() / (RAND_MAX + 1.0)))]); - - /* open O_EXCL & O_CREAT: we are either the sole owner or we fail */ - fd = open(name, O_RDWR | O_CREAT | O_EXCL, 0600); - if (fd == -1) { - /* unlikely, but if we failed because `name' exists, retry */ - if (errno == EEXIST && ++retries < 6) - goto retry; - return -1; - } - - /* truncate the file to `len' bytes */ - if (ftruncate(fd, size) == -1) - goto error; - - if (unlink(name) == -1) - goto error; - - return fd; -error: - close(fd); - return -1; -} - -int ashmem_set_prot_region(int fd, int prot) -{ - return 0; -} - -int ashmem_pin_region(int fd, size_t offset, size_t len) -{ - return ASHMEM_NOT_PURGED; -} - -int ashmem_unpin_region(int fd, size_t offset, size_t len) -{ - return ASHMEM_IS_UNPINNED; -} diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S deleted file mode 100644 index c56ec5d0e3293600102e3487f873527cb5eec8c5..0000000000000000000000000000000000000000 --- a/libcutils/atomic-android-arm.S +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (C) 2005 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <machine/cpu-features.h> - -/* - * NOTE: these atomic operations are SMP safe on all architectures, - * except swap(), see below. - */ - - .text - .align - - .global android_atomic_write - - .global android_atomic_inc - .global android_atomic_dec - - .global android_atomic_add - .global android_atomic_and - .global android_atomic_or - - .global android_atomic_swap - - .global android_atomic_cmpxchg - -/* - * ---------------------------------------------------------------------------- - * int __kernel_cmpxchg(int oldval, int newval, int *ptr) - * clobbered: r3, ip, flags - * return 0 if a swap was made, non-zero otherwise. - */ - - .equ kernel_cmpxchg, 0xFFFF0FC0 - .equ kernel_atomic_base, 0xFFFF0FFF - -/* - * ---------------------------------------------------------------------------- - * android_atomic_write - * input: r0=value, r1=address - * output: void - */ - -android_atomic_write: - stmdb sp!, {r4, lr} - mov r2, r1 - mov r1, r0 -1: @ android_atomic_write - ldr r0, [r2] - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #4 - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) -#else - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) - mov lr, pc - bx r3 -#endif - bcc 1b - ldmia sp!, {r4, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_inc - * input: r0 = address - * output: r0 = old value - */ - -android_atomic_inc: - stmdb sp!, {r4, lr} - mov r2, r0 -1: @ android_atomic_inc - ldr r0, [r2] - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #4 - add r1, r0, #1 - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) -#else - add r1, r0, #1 - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) - mov lr, pc - bx r3 -#endif - bcc 1b - sub r0, r1, #1 - ldmia sp!, {r4, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_dec - * input: r0=address - * output: r0 = old value - */ - -android_atomic_dec: - stmdb sp!, {r4, lr} - mov r2, r0 -1: @ android_atomic_dec - ldr r0, [r2] - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #4 - sub r1, r0, #1 - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) -#else - sub r1, r0, #1 - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) - mov lr, pc - bx r3 -#endif - bcc 1b - add r0, r1, #1 - ldmia sp!, {r4, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_add - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_add: - stmdb sp!, {r4, lr} - mov r2, r1 - mov r4, r0 -1: @ android_atomic_add - ldr r0, [r2] - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #4 - add r1, r0, r4 - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) -#else - add r1, r0, r4 - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) - mov lr, pc - bx r3 -#endif - bcc 1b - sub r0, r1, r4 - ldmia sp!, {r4, lr} - bx lr - - -/* - * ---------------------------------------------------------------------------- - * android_atomic_and - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_and: - stmdb sp!, {r4, r5, lr} - mov r2, r1 /* r2 = address */ - mov r4, r0 /* r4 = the value */ -1: @ android_atomic_and - ldr r0, [r2] /* r0 = address[0] */ - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #8 - mov r5, r0 /* r5 = save address[0] */ - and r1, r0, r4 /* r1 = new value */ - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) /* call cmpxchg() */ -#else - mov r5, r0 /* r5 = save address[0] */ - and r1, r0, r4 /* r1 = new value */ - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) /* call cmpxchg() */ - mov lr, pc - bx r3 -#endif - bcc 1b - mov r0, r5 - ldmia sp!, {r4, r5, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_or - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_or: - stmdb sp!, {r4, r5, lr} - mov r2, r1 /* r2 = address */ - mov r4, r0 /* r4 = the value */ -1: @ android_atomic_or - ldr r0, [r2] /* r0 = address[0] */ - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #8 - mov r5, r0 /* r5 = save address[0] */ - orr r1, r0, r4 /* r1 = new value */ - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) /* call cmpxchg() */ -#else - mov r5, r0 /* r5 = save address[0] */ - orr r1, r0, r4 /* r1 = new value */ - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) /* call cmpxchg() */ - mov lr, pc - bx r3 -#endif - bcc 1b - mov r0, r5 - ldmia sp!, {r4, r5, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_swap - * input: r0=value, r1=address - * output: r0 = old value - */ - -/* FIXME: this is not safe on SMP systems - * a general way to do it is to use kernel_cmpxchg */ - -android_atomic_swap: - swp r0, r0, [r1] - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_cmpxchg - * input: r0=oldvalue, r1=newvalue, r2=address - * output: r0 = 0 (xchg done) or non-zero (xchg not done) - */ - -android_atomic_cmpxchg: - stmdb sp!, {r4, lr} - mov r4, r0 /* r4 = save oldvalue */ -1: @ android_atomic_cmpxchg - mov r3, #kernel_atomic_base -#ifdef __ARM_HAVE_PC_INTERWORK - add lr, pc, #4 - mov r0, r4 /* r0 = oldvalue */ - add pc, r3, #(kernel_cmpxchg - kernel_atomic_base) -#else - mov r0, r4 /* r0 = oldvalue */ - add r3, r3, #(kernel_cmpxchg - kernel_atomic_base) - mov lr, pc - bx r3 -#endif - bcs 2f /* swap was made. we're good, return. */ - ldr r3, [r2] /* swap not made, see if it's because *ptr!=oldvalue */ - cmp r3, r4 - beq 1b -2: @ android_atomic_cmpxchg - ldmia sp!, {r4, lr} - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_cmpxchg_64 - * input: r0-r1=oldvalue, r2-r3=newvalue, arg4 (on stack)=address - * output: r0 = 0 (xchg done) or non-zero (xchg not done) - */ -/* TODO: NEED IMPLEMENTATION FOR THIS ARCHITECTURE */ diff --git a/libcutils/atomic-android-armv6.S b/libcutils/atomic-android-armv6.S deleted file mode 100644 index 64146c177956d2a4f7ad61fb4e8bc7b1b6a45e15..0000000000000000000000000000000000000000 --- a/libcutils/atomic-android-armv6.S +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - - - .text - .align - - .global android_atomic_write - - .global android_atomic_inc - .global android_atomic_dec - - .global android_atomic_add - .global android_atomic_and - .global android_atomic_or - - .global android_atomic_swap - - .global android_atomic_cmpxchg - - - -/* FIXME: On SMP systems memory barriers may be needed */ -#warning "this file is not safe with SMP systems" - - -/* - * ---------------------------------------------------------------------------- - * android_atomic_write - * input: r0=value, r1=address - * output: void - */ - -android_atomic_write: -1: ldrex r12, [r1] - strex r12, r0, [r1] - cmp r12, #0 - bne 1b - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_inc - * input: r0 = address - * output: r0 = old value - */ - -android_atomic_inc: - mov r12, r0 -1: ldrex r0, [r12] - add r2, r0, #1 - strex r1, r2, [r12] - cmp r1, #0 - bxeq lr - b 1b - -/* - * ---------------------------------------------------------------------------- - * android_atomic_dec - * input: r0=address - * output: r0 = old value - */ - -android_atomic_dec: - mov r12, r0 -1: ldrex r0, [r12] - sub r2, r0, #1 - strex r1, r2, [r12] - cmp r1, #0 - bxeq lr - b 1b - - -/* - * ---------------------------------------------------------------------------- - * android_atomic_add - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_add: - mov r12, r0 -1: ldrex r0, [r1] - add r2, r0, r12 - strex r3, r2, [r1] - cmp r3, #0 - bxeq lr - b 1b - -/* - * ---------------------------------------------------------------------------- - * android_atomic_and - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_and: - mov r12, r0 -1: ldrex r0, [r1] - and r2, r0, r12 - strex r3, r2, [r1] - cmp r3, #0 - bxeq lr - b 1b - - -/* - * ---------------------------------------------------------------------------- - * android_atomic_or - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_or: - mov r12, r0 -1: ldrex r0, [r1] - orr r2, r0, r12 - strex r3, r2, [r1] - cmp r3, #0 - bxeq lr - b 1b - -/* - * ---------------------------------------------------------------------------- - * android_atomic_swap - * input: r0=value, r1=address - * output: r0 = old value - */ - -android_atomic_swap: - swp r0, r0, [r1] - bx lr - -/* - * ---------------------------------------------------------------------------- - * android_atomic_cmpxchg - * input: r0=oldvalue, r1=newvalue, r2=address - * output: r0 = 0 (xchg done) or non-zero (xchg not done) - */ - -android_atomic_cmpxchg: - mov r12, r1 - ldrex r3, [r2] - eors r0, r0, r3 - strexeq r0, r12, [r2] - bx lr - - - -/* - * ---------------------------------------------------------------------------- - * android_atomic_cmpxchg_64 - * input: r0-r1=oldvalue, r2-r3=newvalue, arg4 (on stack)=address - * output: r0 = 0 (xchg done) or non-zero (xchg not done) - */ -/* TODO: NEED IMPLEMENTATION FOR THIS ARCHITECTURE */ diff --git a/libcutils/atomic.c b/libcutils/atomic.c deleted file mode 100644 index 65d7af0af006c705ccf29ad70749a0c586aaa1fb..0000000000000000000000000000000000000000 --- a/libcutils/atomic.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/atomic.h> -#ifdef HAVE_WIN32_THREADS -#include <windows.h> -#else -#include <sched.h> -#endif - -/*****************************************************************************/ -#if defined(HAVE_MACOSX_IPC) - -#include <libkern/OSAtomic.h> - -void android_atomic_write(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (OSAtomicCompareAndSwap32Barrier(oldValue, value, (int32_t*)addr) == 0); -} - -int32_t android_atomic_inc(volatile int32_t* addr) { - return OSAtomicIncrement32Barrier((int32_t*)addr)-1; -} - -int32_t android_atomic_dec(volatile int32_t* addr) { - return OSAtomicDecrement32Barrier((int32_t*)addr)+1; -} - -int32_t android_atomic_add(int32_t value, volatile int32_t* addr) { - return OSAtomicAdd32Barrier(value, (int32_t*)addr)-value; -} - -int32_t android_atomic_and(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (OSAtomicCompareAndSwap32Barrier(oldValue, oldValue&value, (int32_t*)addr) == 0); - return oldValue; -} - -int32_t android_atomic_or(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (OSAtomicCompareAndSwap32Barrier(oldValue, oldValue|value, (int32_t*)addr) == 0); - return oldValue; -} - -int32_t android_atomic_swap(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, value, addr)); - return oldValue; -} - -int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, volatile int32_t* addr) { - return OSAtomicCompareAndSwap32Barrier(oldvalue, newvalue, (int32_t*)addr) == 0; -} - -#if defined(__ppc__) \ - || defined(__PPC__) \ - || defined(__powerpc__) \ - || defined(__powerpc) \ - || defined(__POWERPC__) \ - || defined(_M_PPC) \ - || defined(__PPC) -#define NEED_QUASIATOMICS 1 -#else - -int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, - volatile int64_t* addr) { - return OSAtomicCompareAndSwap64Barrier(oldvalue, newvalue, - (int64_t*)addr) == 0; -} - -int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) { - int64_t oldValue; - do { - oldValue = *addr; - } while (android_quasiatomic_cmpxchg_64(oldValue, value, addr)); - return oldValue; -} - -int64_t android_quasiatomic_read_64(volatile int64_t* addr) { - return OSAtomicAdd64Barrier(0, addr); -} - -#endif - - -/*****************************************************************************/ -#elif defined(__i386__) || defined(__x86_64__) - -void android_atomic_write(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, value, addr)); -} - -int32_t android_atomic_inc(volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, oldValue+1, addr)); - return oldValue; -} - -int32_t android_atomic_dec(volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, oldValue-1, addr)); - return oldValue; -} - -int32_t android_atomic_add(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, oldValue+value, addr)); - return oldValue; -} - -int32_t android_atomic_and(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, oldValue&value, addr)); - return oldValue; -} - -int32_t android_atomic_or(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, oldValue|value, addr)); - return oldValue; -} - -int32_t android_atomic_swap(int32_t value, volatile int32_t* addr) { - int32_t oldValue; - do { - oldValue = *addr; - } while (android_atomic_cmpxchg(oldValue, value, addr)); - return oldValue; -} - -int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, volatile int32_t* addr) { - int xchg; - asm volatile - ( - " lock; cmpxchg %%ecx, (%%edx);" - " setne %%al;" - " andl $1, %%eax" - : "=a" (xchg) - : "a" (oldvalue), "c" (newvalue), "d" (addr) - ); - return xchg; -} - -#define NEED_QUASIATOMICS 1 - -/*****************************************************************************/ -#elif __arm__ -// Most of the implementation is in atomic-android-arm.s. - -// on the device, we implement the 64-bit atomic operations through -// mutex locking. normally, this is bad because we must initialize -// a pthread_mutex_t before being able to use it, and this means -// having to do an initialization check on each function call, and -// that's where really ugly things begin... -// -// BUT, as a special twist, we take advantage of the fact that in our -// pthread library, a mutex is simply a volatile word whose value is always -// initialized to 0. In other words, simply declaring a static mutex -// object initializes it ! -// -// another twist is that we use a small array of mutexes to dispatch -// the contention locks from different memory addresses -// - -#include <pthread.h> - -#define SWAP_LOCK_COUNT 32U -static pthread_mutex_t _swap_locks[SWAP_LOCK_COUNT]; - -#define SWAP_LOCK(addr) \ - &_swap_locks[((unsigned)(void*)(addr) >> 3U) % SWAP_LOCK_COUNT] - - -int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) { - int64_t oldValue; - pthread_mutex_t* lock = SWAP_LOCK(addr); - - pthread_mutex_lock(lock); - - oldValue = *addr; - *addr = value; - - pthread_mutex_unlock(lock); - return oldValue; -} - -int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, - volatile int64_t* addr) { - int result; - pthread_mutex_t* lock = SWAP_LOCK(addr); - - pthread_mutex_lock(lock); - - if (*addr == oldvalue) { - *addr = newvalue; - result = 0; - } else { - result = 1; - } - pthread_mutex_unlock(lock); - return result; -} - -int64_t android_quasiatomic_read_64(volatile int64_t* addr) { - int64_t result; - pthread_mutex_t* lock = SWAP_LOCK(addr); - - pthread_mutex_lock(lock); - result = *addr; - pthread_mutex_unlock(lock); - return result; -} - -#else - -#error "Unsupported atomic operations for this platform" - -#endif - - - -#if NEED_QUASIATOMICS - -/* Note that a spinlock is *not* a good idea in general - * since they can introduce subtle issues. For example, - * a real-time thread trying to acquire a spinlock already - * acquired by another thread will never yeld, making the - * CPU loop endlessly! - * - * However, this code is only used on the Linux simulator - * so it's probably ok for us. - * - * The alternative is to use a pthread mutex, but - * these must be initialized before being used, and - * then you have the problem of lazily initializing - * a mutex without any other synchronization primitive. - */ - -/* global spinlock for all 64-bit quasiatomic operations */ -static int32_t quasiatomic_spinlock = 0; - -int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue, - volatile int64_t* addr) { - int result; - - while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) { -#ifdef HAVE_WIN32_THREADS - Sleep(0); -#else - sched_yield(); -#endif - } - - if (*addr == oldvalue) { - *addr = newvalue; - result = 0; - } else { - result = 1; - } - - android_atomic_swap(0, &quasiatomic_spinlock); - - return result; -} - -int64_t android_quasiatomic_read_64(volatile int64_t* addr) { - int64_t result; - - while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) { -#ifdef HAVE_WIN32_THREADS - Sleep(0); -#else - sched_yield(); -#endif - } - - result = *addr; - android_atomic_swap(0, &quasiatomic_spinlock); - - return result; -} - -int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) { - int64_t result; - - while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) { -#ifdef HAVE_WIN32_THREADS - Sleep(0); -#else - sched_yield(); -#endif - } - - result = *addr; - *addr = value; - android_atomic_swap(0, &quasiatomic_spinlock); - - return result; -} - -#endif diff --git a/libcutils/buffer.c b/libcutils/buffer.c deleted file mode 100644 index f34b8f892aec23c4ea36d5f0e1a98e9aec206c18..0000000000000000000000000000000000000000 --- a/libcutils/buffer.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "buffer" - -#include <assert.h> -#include <errno.h> -#include <stdlib.h> -#include <unistd.h> - -#include "buffer.h" -#include "loghack.h" - -Buffer* bufferCreate(size_t capacity) { - Buffer* buffer = malloc(sizeof(Buffer)); - if (buffer == NULL) { - return NULL; - } - buffer->capacity = capacity; - buffer->expected = 0; - buffer->data = malloc(capacity); - if (buffer->data == NULL) { - free(buffer); - return NULL; - } - return buffer; -} - -void bufferFree(Buffer* buffer) { - free(buffer->data); - free(buffer); -} - -Buffer* bufferWrap(char* data, size_t capacity, size_t size) { - Buffer* buffer = malloc(sizeof(Buffer)); - if (buffer == NULL) { - return NULL; - } - - buffer->data = data; - buffer->capacity = capacity; - buffer->size = size; - buffer->expected = 0; - return buffer; -} - -int bufferPrepareForRead(Buffer* buffer, size_t expected) { - if (expected > buffer->capacity) { - // Expand buffer. - char* expanded = realloc(buffer->data, expected); - if (expanded == NULL) { - errno = ENOMEM; - return -1; - } - buffer->capacity = expected; - buffer->data = expanded; - } - - buffer->size = 0; - buffer->expected = expected; - return 0; -} - -ssize_t bufferRead(Buffer* buffer, int fd) { - assert(buffer->size < buffer->expected); - - ssize_t bytesRead = read(fd, - buffer->data + buffer->size, - buffer->expected - buffer->size); - - if (bytesRead > 0) { - buffer->size += bytesRead; - return buffer->size; - } - - return bytesRead; -} - -void bufferPrepareForWrite(Buffer* buffer) { - buffer->remaining = buffer->size; -} - -ssize_t bufferWrite(Buffer* buffer, int fd) { - assert(buffer->remaining > 0); - assert(buffer->remaining <= buffer->size); - - ssize_t bytesWritten = write(fd, - buffer->data + buffer->size - buffer->remaining, - buffer->remaining); - - if (bytesWritten >= 0) { - buffer->remaining -= bytesWritten; - - LOGD("Buffer bytes written: %d", (int) bytesWritten); - LOGD("Buffer size: %d", (int) buffer->size); - LOGD("Buffer remaining: %d", (int) buffer->remaining); - - return buffer->remaining; - } - - return bytesWritten; -} - diff --git a/libcutils/buffer.h b/libcutils/buffer.h deleted file mode 100644 index d8bc108ee7c6ffde0a1d19608eea4ec324f5550d..0000000000000000000000000000000000000000 --- a/libcutils/buffer.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Byte buffer utilities. - */ - -#ifndef __BUFFER_H -#define __BUFFER_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <stdlib.h> - -/** - * Byte buffer of known size. Keeps track of how much data has been read - * into or written out of the buffer. - */ -typedef struct { - /** Buffered data. */ - char* data; - - union { - /** For reading. # of bytes we expect. */ - size_t expected; - - /** For writing. # of bytes to write. */ - size_t remaining; - }; - - /** Actual # of bytes in the buffer. */ - size_t size; - - /** Amount of memory allocated for this buffer. */ - size_t capacity; -} Buffer; - -/** - * Returns true if all data has been read into the buffer. - */ -#define bufferReadComplete(buffer) (buffer->expected == buffer->size) - -/** - * Returns true if the buffer has been completely written. - */ -#define bufferWriteComplete(buffer) (buffer->remaining == 0) - -/** - * Creates a new buffer with the given initial capacity. - */ -Buffer* bufferCreate(size_t initialCapacity); - -/** - * Wraps an existing byte array. - */ -Buffer* bufferWrap(char* data, size_t capacity, size_t size); - -/** - * Frees and its data. - */ -void bufferFree(Buffer* buffer); - -/** - * Prepares buffer to read 'expected' number of bytes. Expands capacity if - * necessary. Returns 0 if successful or -1 if an error occurs allocating - * memory. - */ -int bufferPrepareForRead(Buffer* buffer, size_t expected); - -/** - * Reads some data into a buffer. Returns -1 in case of an error and sets - * errno (see read()). Returns 0 for EOF. Updates buffer->size and returns - * the new size after a succesful read. - * - * Precondition: buffer->size < buffer->expected - */ -ssize_t bufferRead(Buffer* buffer, int fd); - -/** - * Prepares a buffer to be written out. - */ -void bufferPrepareForWrite(Buffer* buffer); - -/** - * Writes data from buffer to the given fd. Returns -1 and sets errno in case - * of an error. Updates buffer->remaining and returns the number of remaining - * bytes to be written after a successful write. - * - * Precondition: buffer->remaining > 0 - */ -ssize_t bufferWrite(Buffer* buffer, int fd); - -#ifdef __cplusplus -} -#endif - -#endif /* __BUFFER_H */ diff --git a/libcutils/config_utils.c b/libcutils/config_utils.c deleted file mode 100644 index 75fa6c6d4dfbfd08921489f346e706b7619dd763..0000000000000000000000000000000000000000 --- a/libcutils/config_utils.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <fcntl.h> -#include <unistd.h> - -#include <cutils/config_utils.h> -#include <cutils/misc.h> - -cnode* config_node(const char *name, const char *value) -{ - cnode *node; - - node = calloc(sizeof(cnode), 1); - if(node) { - node->name = name ? name : ""; - node->value = value ? value : ""; - } - - return node; -} - -cnode* config_find(cnode *root, const char *name) -{ - cnode *node, *match = NULL; - - /* we walk the whole list, as we need to return the last (newest) entry */ - for(node = root->first_child; node; node = node->next) - if(!strcmp(node->name, name)) - match = node; - - return match; -} - -static cnode* _config_create(cnode *root, const char *name) -{ - cnode *node; - - node = config_node(name, NULL); - - if(root->last_child) - root->last_child->next = node; - else - root->first_child = node; - - root->last_child = node; - - return node; -} - -int config_bool(cnode *root, const char *name, int _default) -{ - cnode *node; - - node = config_find(root, name); - if(!node) - return _default; - - switch(node->value[0]) { - case 'y': - case 'Y': - case '1': - return 1; - default: - return 0; - } -} - -const char* config_str(cnode *root, const char *name, const char *_default) -{ - cnode *node; - - node = config_find(root, name); - if(!node) - return _default; - return node->value; -} - -void config_set(cnode *root, const char *name, const char *value) -{ - cnode *node; - - node = config_find(root, name); - if(node) - node->value = value; - else { - node = _config_create(root, name); - node->value = value; - } -} - -#define T_EOF 0 -#define T_TEXT 1 -#define T_DOT 2 -#define T_OBRACE 3 -#define T_CBRACE 4 - -typedef struct -{ - char *data; - char *text; - int len; - char next; -} cstate; - -static int _lex(cstate *cs, int value) -{ - char c; - char *s; - char *data; - - data = cs->data; - - if(cs->next != 0) { - c = cs->next; - cs->next = 0; - goto got_c; - } - -restart: - for(;;) { - c = *data++; - got_c: - if(isspace(c)) - continue; - - switch(c) { - case 0: - return T_EOF; - - case '#': - for(;;) { - switch(*data) { - case 0: - cs->data = data; - return T_EOF; - case '\n': - cs->data = data + 1; - goto restart; - default: - data++; - } - } - break; - - case '.': - cs->data = data; - return T_DOT; - - case '{': - cs->data = data; - return T_OBRACE; - - case '}': - cs->data = data; - return T_CBRACE; - - default: - s = data - 1; - - if(value) { - for(;;) { - if(*data == 0) { - cs->data = data; - break; - } - if(*data == '\n') { - cs->data = data + 1; - *data-- = 0; - break; - } - data++; - } - - /* strip trailing whitespace */ - while(data > s){ - if(!isspace(*data)) break; - *data-- = 0; - } - - goto got_text; - } else { - for(;;) { - if(isspace(*data)) { - *data = 0; - cs->data = data + 1; - goto got_text; - } - switch(*data) { - case 0: - cs->data = data; - goto got_text; - case '.': - case '{': - case '}': - cs->next = *data; - *data = 0; - cs->data = data + 1; - goto got_text; - default: - data++; - } - } - } - } - } - -got_text: - cs->text = s; - return T_TEXT; -} - -#if 0 -char *TOKENNAMES[] = { "EOF", "TEXT", "DOT", "OBRACE", "CBRACE" }; - -static int lex(cstate *cs, int value) -{ - int tok = _lex(cs, value); - printf("TOKEN(%d) %s %s\n", value, TOKENNAMES[tok], - tok == T_TEXT ? cs->text : ""); - return tok; -} -#else -#define lex(cs,v) _lex(cs,v) -#endif - -static int parse_expr(cstate *cs, cnode *node); - -static int parse_block(cstate *cs, cnode *node) -{ - for(;;){ - switch(lex(cs, 0)){ - case T_TEXT: - if(parse_expr(cs, node)) return -1; - continue; - - case T_CBRACE: - return 0; - - default: - return -1; - } - } -} - -static int parse_expr(cstate *cs, cnode *root) -{ - cnode *node; - - /* last token was T_TEXT */ - node = config_find(root, cs->text); - if(!node || *node->value) - node = _config_create(root, cs->text); - - for(;;) { - switch(lex(cs, 1)) { - case T_DOT: - if(lex(cs, 0) != T_TEXT) - return -1; - node = _config_create(node, cs->text); - continue; - - case T_TEXT: - node->value = cs->text; - return 0; - - case T_OBRACE: - return parse_block(cs, node); - - default: - return -1; - } - } -} - -void config_load(cnode *root, char *data) -{ - if(data != 0) { - cstate cs; - cs.data = data; - cs.next = 0; - - for(;;) { - switch(lex(&cs, 0)) { - case T_TEXT: - if(parse_expr(&cs, root)) - return; - break; - default: - return; - } - } - } -} - -void config_load_file(cnode *root, const char *fn) -{ - char *data; - data = load_file(fn, 0); - config_load(root, data); -} diff --git a/libcutils/cpu_info.c b/libcutils/cpu_info.c deleted file mode 100644 index 23dda8aa14d88d6d85610ca9cd2a3169e455b42f..0000000000000000000000000000000000000000 --- a/libcutils/cpu_info.c +++ /dev/null @@ -1,83 +0,0 @@ -/* libs/cutils/cpu_info.c -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/cpu_info.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -// we cache the serial number here. -// this is also used as a fgets() line buffer when we are reading /proc/cpuinfo -static char serial_number[100] = { 0 }; - -extern const char* get_cpu_serial_number(void) -{ - if (serial_number[0] == 0) - { - FILE* file; - char* chp, *end; - char* whitespace; - int length; - - // read serial number from /proc/cpuinfo - file = fopen("proc/cpuinfo", "r"); - if (! file) - return NULL; - - while ((chp = fgets(serial_number, sizeof(serial_number), file)) != NULL) - { - // look for something like "Serial : 999206122a03591c" - - if (strncmp(chp, "Serial", 6) != 0) - continue; - - chp = strchr(chp, ':'); - if (!chp) - continue; - - // skip colon and whitespace - while ( *(++chp) == ' ') {} - - // truncate trailing whitespace - end = chp; - while (*end && *end != ' ' && *end != '\t' && *end != '\n' && *end != '\r') - ++end; - *end = 0; - - whitespace = strchr(chp, ' '); - if (whitespace) - *whitespace = 0; - whitespace = strchr(chp, '\t'); - if (whitespace) - *whitespace = 0; - whitespace = strchr(chp, '\r'); - if (whitespace) - *whitespace = 0; - whitespace = strchr(chp, '\n'); - if (whitespace) - *whitespace = 0; - - // shift serial number to beginning of the buffer - memmove(serial_number, chp, strlen(chp) + 1); - break; - } - - fclose(file); - } - - return (serial_number[0] ? serial_number : NULL); -} diff --git a/libcutils/dir_hash.c b/libcutils/dir_hash.c deleted file mode 100644 index be14af65c55f59449e60f042b537b1df09571bd8..0000000000000000000000000000000000000000 --- a/libcutils/dir_hash.c +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <dirent.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sha1.h> -#include <unistd.h> -#include <limits.h> - -#include <sys/stat.h> - -#include <netinet/in.h> -#include <resolv.h> - -#include <cutils/dir_hash.h> - -/** - * Copies, if it fits within max_output_string bytes, into output_string - * a hash of the contents, size, permissions, uid, and gid of the file - * specified by path, using the specified algorithm. Returns the length - * of the output string, or a negative number if the buffer is too short. - */ -int get_file_hash(HashAlgorithm algorithm, const char *path, - char *output_string, size_t max_output_string) { - SHA1_CTX context; - struct stat sb; - unsigned char md[SHA1_DIGEST_LENGTH]; - int used; - size_t n; - - if (algorithm != SHA_1) { - errno = EINVAL; - return -1; - } - - if (stat(path, &sb) != 0) { - return -1; - } - - if (S_ISLNK(sb.st_mode)) { - char buf[PATH_MAX]; - int len; - - len = readlink(path, buf, sizeof(buf)); - if (len < 0) { - return -1; - } - - SHA1Init(&context); - SHA1Update(&context, (unsigned char *) buf, len); - SHA1Final(md, &context); - } else if (S_ISREG(sb.st_mode)) { - char buf[10000]; - FILE *f = fopen(path, "rb"); - int len; - - if (f == NULL) { - return -1; - } - - SHA1Init(&context); - - while ((len = fread(buf, 1, sizeof(buf), f)) > 0) { - SHA1Update(&context, (unsigned char *) buf, len); - } - - if (ferror(f)) { - fclose(f); - return -1; - } - - fclose(f); - SHA1Final(md, &context); - } - - if (S_ISLNK(sb.st_mode) || S_ISREG(sb.st_mode)) { - used = b64_ntop(md, SHA1_DIGEST_LENGTH, - output_string, max_output_string); - if (used < 0) { - errno = ENOSPC; - return -1; - } - - n = snprintf(output_string + used, max_output_string - used, - " %d 0%o %d %d", (int) sb.st_size, sb.st_mode, - (int) sb.st_uid, (int) sb.st_gid); - } else { - n = snprintf(output_string, max_output_string, - "- - 0%o %d %d", sb.st_mode, - (int) sb.st_uid, (int) sb.st_gid); - } - - if (n >= max_output_string - used) { - errno = ENOSPC; - return -(used + n); - } - - return used + n; -} - -struct list { - char *name; - struct list *next; -}; - -static int cmp(const void *a, const void *b) { - struct list *const *ra = a; - struct list *const *rb = b; - - return strcmp((*ra)->name, (*rb)->name); -} - -static int recurse(HashAlgorithm algorithm, const char *directory_path, - struct list **out) { - struct list *list = NULL; - struct list *f; - - struct dirent *de; - DIR *d = opendir(directory_path); - - if (d == NULL) { - return -1; - } - - while ((de = readdir(d)) != NULL) { - if (strcmp(de->d_name, ".") == 0) { - continue; - } - if (strcmp(de->d_name, "..") == 0) { - continue; - } - - char *name = malloc(strlen(de->d_name) + 1); - struct list *node = malloc(sizeof(struct list)); - - if (name == NULL || node == NULL) { - struct list *next; - for (f = list; f != NULL; f = next) { - next = f->next; - free(f->name); - free(f); - } - - free(name); - free(node); - return -1; - } - - strcpy(name, de->d_name); - - node->name = name; - node->next = list; - list = node; - } - - closedir(d); - - for (f = list; f != NULL; f = f->next) { - struct stat sb; - char *name; - char outstr[NAME_MAX + 100]; - char *keep; - struct list *res; - - name = malloc(strlen(f->name) + strlen(directory_path) + 2); - if (name == NULL) { - struct list *next; - for (f = list; f != NULL; f = f->next) { - next = f->next; - free(f->name); - free(f); - } - for (f = *out; f != NULL; f = f->next) { - next = f->next; - free(f->name); - free(f); - } - *out = NULL; - return -1; - } - - sprintf(name, "%s/%s", directory_path, f->name); - - int len = get_file_hash(algorithm, name, - outstr, sizeof(outstr)); - if (len < 0) { - // should not happen - return -1; - } - - keep = malloc(len + strlen(name) + 3); - res = malloc(sizeof(struct list)); - - if (keep == NULL || res == NULL) { - struct list *next; - for (f = list; f != NULL; f = f->next) { - next = f->next; - free(f->name); - free(f); - } - for (f = *out; f != NULL; f = f->next) { - next = f->next; - free(f->name); - free(f); - } - *out = NULL; - - free(keep); - free(res); - return -1; - } - - sprintf(keep, "%s %s\n", name, outstr); - - res->name = keep; - res->next = *out; - *out = res; - - if ((stat(name, &sb) == 0) && S_ISDIR(sb.st_mode)) { - if (recurse(algorithm, name, out) < 0) { - struct list *next; - for (f = list; f != NULL; f = next) { - next = f->next; - free(f->name); - free(f); - } - - return -1; - } - } - } - - struct list *next; - for (f = list; f != NULL; f = next) { - next = f->next; - - free(f->name); - free(f); - } -} - -/** - * Allocates a string containing the names and hashes of all files recursively - * reached under the specified directory_path, using the specified algorithm. - * The string is returned as *output_string; the return value is the length - * of the string, or a negative number if there was a failure. - */ -int get_recursive_hash_manifest(HashAlgorithm algorithm, - const char *directory_path, - char **output_string) { - struct list *out = NULL; - struct list *r; - struct list **list; - int count = 0; - int len = 0; - int retlen = 0; - int i; - char *buf; - - if (recurse(algorithm, directory_path, &out) < 0) { - return -1; - } - - for (r = out; r != NULL; r = r->next) { - count++; - len += strlen(r->name); - } - - list = malloc(count * sizeof(struct list *)); - if (list == NULL) { - struct list *next; - for (r = out; r != NULL; r = next) { - next = r->next; - free(r->name); - free(r); - } - return -1; - } - - count = 0; - for (r = out; r != NULL; r = r->next) { - list[count++] = r; - } - - qsort(list, count, sizeof(struct list *), cmp); - - buf = malloc(len + 1); - if (buf == NULL) { - struct list *next; - for (r = out; r != NULL; r = next) { - next = r->next; - free(r->name); - free(r); - } - free(list); - return -1; - } - - for (i = 0; i < count; i++) { - int n = strlen(list[i]->name); - - strcpy(buf + retlen, list[i]->name); - retlen += n; - } - - free(list); - - struct list *next; - for (r = out; r != NULL; r = next) { - next = r->next; - - free(r->name); - free(r); - } - - *output_string = buf; - return retlen; -} diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c deleted file mode 100644 index 1ced147b83eb365300186d76cd22f049269d20f0..0000000000000000000000000000000000000000 --- a/libcutils/dlmalloc_stubs.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* No-op stubs for functions defined in system/bionic/bionic/dlmalloc.c. - */ -void dlmalloc_walk_free_pages() -{ -} - -void dlmalloc_walk_heap() -{ -} - -void dlmalloc_trim() -{ -} diff --git a/libcutils/fdevent.c b/libcutils/fdevent.c deleted file mode 100644 index 4cf46faf768443f09118ae44350583bc05b4419d..0000000000000000000000000000000000000000 --- a/libcutils/fdevent.c +++ /dev/null @@ -1,506 +0,0 @@ -/* http://frotznet.googlecode.com/svn/trunk/utils/fdevent.c -** -** Copyright 2006, Brian Swetland <swetland@frotz.net> -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -#include <fcntl.h> - -#include <stdarg.h> -#include <stddef.h> - -#include <cutils/fdevent.h> - -#define TRACE(x...) fprintf(stderr,x) - -#define DEBUG 0 - -static void fatal(const char *fn, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - fprintf(stderr, "%s:", fn); - vfprintf(stderr, fmt, ap); - va_end(ap); - abort(); -} - -#define FATAL(x...) fatal(__FUNCTION__, x) - -#if DEBUG -static void dump_fde(fdevent *fde, const char *info) -{ - fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd, - fde->state & FDE_READ ? 'R' : ' ', - fde->state & FDE_WRITE ? 'W' : ' ', - fde->state & FDE_ERROR ? 'E' : ' ', - info); -} -#else -#define dump_fde(fde, info) do { } while(0) -#endif - -#define FDE_EVENTMASK 0x00ff -#define FDE_STATEMASK 0xff00 - -#define FDE_ACTIVE 0x0100 -#define FDE_PENDING 0x0200 -#define FDE_CREATED 0x0400 - -static void fdevent_plist_enqueue(fdevent *node); -static void fdevent_plist_remove(fdevent *node); -static fdevent *fdevent_plist_dequeue(void); - -static fdevent list_pending = { - .next = &list_pending, - .prev = &list_pending, -}; - -static fdevent **fd_table = 0; -static int fd_table_max = 0; - -#ifdef CRAPTASTIC -//HAVE_EPOLL - -#include <sys/epoll.h> - -static int epoll_fd = -1; - -static void fdevent_init() -{ - /* XXX: what's a good size for the passed in hint? */ - epoll_fd = epoll_create(256); - - if(epoll_fd < 0) { - perror("epoll_create() failed"); - exit(1); - } - - /* mark for close-on-exec */ - fcntl(epoll_fd, F_SETFD, FD_CLOEXEC); -} - -static void fdevent_connect(fdevent *fde) -{ - struct epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - ev.events = 0; - ev.data.ptr = fde; - -#if 0 - if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { - perror("epoll_ctl() failed\n"); - exit(1); - } -#endif -} - -static void fdevent_disconnect(fdevent *fde) -{ - struct epoll_event ev; - - memset(&ev, 0, sizeof(ev)); - ev.events = 0; - ev.data.ptr = fde; - - /* technically we only need to delete if we - ** were actively monitoring events, but let's - ** be aggressive and do it anyway, just in case - ** something's out of sync - */ - epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev); -} - -static void fdevent_update(fdevent *fde, unsigned events) -{ - struct epoll_event ev; - int active; - - active = (fde->state & FDE_EVENTMASK) != 0; - - memset(&ev, 0, sizeof(ev)); - ev.events = 0; - ev.data.ptr = fde; - - if(events & FDE_READ) ev.events |= EPOLLIN; - if(events & FDE_WRITE) ev.events |= EPOLLOUT; - if(events & FDE_ERROR) ev.events |= (EPOLLERR | EPOLLHUP); - - fde->state = (fde->state & FDE_STATEMASK) | events; - - if(active) { - /* we're already active. if we're changing to *no* - ** events being monitored, we need to delete, otherwise - ** we need to just modify - */ - if(ev.events) { - if(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fde->fd, &ev)) { - perror("epoll_ctl() failed\n"); - exit(1); - } - } else { - if(epoll_ctl(epoll_fd, EPOLL_CTL_DEL, fde->fd, &ev)) { - perror("epoll_ctl() failed\n"); - exit(1); - } - } - } else { - /* we're not active. if we're watching events, we need - ** to add, otherwise we can just do nothing - */ - if(ev.events) { - if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fde->fd, &ev)) { - perror("epoll_ctl() failed\n"); - exit(1); - } - } - } -} - -static void fdevent_process() -{ - struct epoll_event events[256]; - fdevent *fde; - int i, n; - - n = epoll_wait(epoll_fd, events, 256, -1); - - if(n < 0) { - if(errno == EINTR) return; - perror("epoll_wait"); - exit(1); - } - - for(i = 0; i < n; i++) { - struct epoll_event *ev = events + i; - fde = ev->data.ptr; - - if(ev->events & EPOLLIN) { - fde->events |= FDE_READ; - } - if(ev->events & EPOLLOUT) { - fde->events |= FDE_WRITE; - } - if(ev->events & (EPOLLERR | EPOLLHUP)) { - fde->events |= FDE_ERROR; - } - if(fde->events) { - if(fde->state & FDE_PENDING) continue; - fde->state |= FDE_PENDING; - fdevent_plist_enqueue(fde); - } - } -} - -#else /* USE_SELECT */ - -#ifdef HAVE_WINSOCK -#include <winsock2.h> -#else -#include <sys/select.h> -#endif - -static fd_set read_fds; -static fd_set write_fds; -static fd_set error_fds; - -static int select_n = 0; - -static void fdevent_init(void) -{ - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - FD_ZERO(&error_fds); -} - -static void fdevent_connect(fdevent *fde) -{ - if(fde->fd >= select_n) { - select_n = fde->fd + 1; - } -} - -static void fdevent_disconnect(fdevent *fde) -{ - int i, n; - - FD_CLR(fde->fd, &read_fds); - FD_CLR(fde->fd, &write_fds); - FD_CLR(fde->fd, &error_fds); - - for(n = 0, i = 0; i < select_n; i++) { - if(fd_table[i] != 0) n = i; - } - select_n = n + 1; -} - -static void fdevent_update(fdevent *fde, unsigned events) -{ - if(events & FDE_READ) { - FD_SET(fde->fd, &read_fds); - } else { - FD_CLR(fde->fd, &read_fds); - } - if(events & FDE_WRITE) { - FD_SET(fde->fd, &write_fds); - } else { - FD_CLR(fde->fd, &write_fds); - } - if(events & FDE_ERROR) { - FD_SET(fde->fd, &error_fds); - } else { - FD_CLR(fde->fd, &error_fds); - } - - fde->state = (fde->state & FDE_STATEMASK) | events; -} - -static void fdevent_process() -{ - int i, n; - fdevent *fde; - unsigned events; - fd_set rfd, wfd, efd; - - memcpy(&rfd, &read_fds, sizeof(fd_set)); - memcpy(&wfd, &write_fds, sizeof(fd_set)); - memcpy(&efd, &error_fds, sizeof(fd_set)); - - n = select(select_n, &rfd, &wfd, &efd, 0); - - if(n < 0) { - if(errno == EINTR) return; - perror("select"); - return; - } - - for(i = 0; (i < select_n) && (n > 0); i++) { - events = 0; - if(FD_ISSET(i, &rfd)) events |= FDE_READ; - if(FD_ISSET(i, &wfd)) events |= FDE_WRITE; - if(FD_ISSET(i, &efd)) events |= FDE_ERROR; - - if(events) { - n--; - - fde = fd_table[i]; - if(fde == 0) FATAL("missing fde for fd %d\n", i); - - fde->events |= events; - - if(fde->state & FDE_PENDING) continue; - fde->state |= FDE_PENDING; - fdevent_plist_enqueue(fde); - } - } -} - -#endif - -static void fdevent_register(fdevent *fde) -{ - if(fde->fd < 0) { - FATAL("bogus negative fd (%d)\n", fde->fd); - } - - if(fde->fd >= fd_table_max) { - int oldmax = fd_table_max; - if(fde->fd > 32000) { - FATAL("bogus huuuuge fd (%d)\n", fde->fd); - } - if(fd_table_max == 0) { - fdevent_init(); - fd_table_max = 256; - } - while(fd_table_max <= fde->fd) { - fd_table_max *= 2; - } - fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max); - if(fd_table == 0) { - FATAL("could not expand fd_table to %d entries\n", fd_table_max); - } - memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax)); - } - - fd_table[fde->fd] = fde; -} - -static void fdevent_unregister(fdevent *fde) -{ - if((fde->fd < 0) || (fde->fd >= fd_table_max)) { - FATAL("fd out of range (%d)\n", fde->fd); - } - - if(fd_table[fde->fd] != fde) { - FATAL("fd_table out of sync"); - } - - fd_table[fde->fd] = 0; - - if(!(fde->state & FDE_DONT_CLOSE)) { - dump_fde(fde, "close"); - close(fde->fd); - } -} - -static void fdevent_plist_enqueue(fdevent *node) -{ - fdevent *list = &list_pending; - - node->next = list; - node->prev = list->prev; - node->prev->next = node; - list->prev = node; -} - -static void fdevent_plist_remove(fdevent *node) -{ - node->prev->next = node->next; - node->next->prev = node->prev; - node->next = 0; - node->prev = 0; -} - -static fdevent *fdevent_plist_dequeue(void) -{ - fdevent *list = &list_pending; - fdevent *node = list->next; - - if(node == list) return 0; - - list->next = node->next; - list->next->prev = list; - node->next = 0; - node->prev = 0; - - return node; -} - -fdevent *fdevent_create(int fd, fd_func func, void *arg) -{ - fdevent *fde = (fdevent*) malloc(sizeof(fdevent)); - if(fde == 0) return 0; - fdevent_install(fde, fd, func, arg); - fde->state |= FDE_CREATED; - return fde; -} - -void fdevent_destroy(fdevent *fde) -{ - if(fde == 0) return; - if(!(fde->state & FDE_CREATED)) { - FATAL("fde %p not created by fdevent_create()\n", fde); - } - fdevent_remove(fde); -} - -void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg) -{ - memset(fde, 0, sizeof(fdevent)); - fde->state = FDE_ACTIVE; - fde->fd = fd; - fde->func = func; - fde->arg = arg; - -#ifndef HAVE_WINSOCK - fcntl(fd, F_SETFL, O_NONBLOCK); -#endif - fdevent_register(fde); - dump_fde(fde, "connect"); - fdevent_connect(fde); - fde->state |= FDE_ACTIVE; -} - -void fdevent_remove(fdevent *fde) -{ - if(fde->state & FDE_PENDING) { - fdevent_plist_remove(fde); - } - - if(fde->state & FDE_ACTIVE) { - fdevent_disconnect(fde); - dump_fde(fde, "disconnect"); - fdevent_unregister(fde); - } - - fde->state = 0; - fde->events = 0; -} - - -void fdevent_set(fdevent *fde, unsigned events) -{ - events &= FDE_EVENTMASK; - - if((fde->state & FDE_EVENTMASK) == events) return; - - if(fde->state & FDE_ACTIVE) { - fdevent_update(fde, events); - dump_fde(fde, "update"); - } - - fde->state = (fde->state & FDE_STATEMASK) | events; - - if(fde->state & FDE_PENDING) { - /* if we're pending, make sure - ** we don't signal an event that - ** is no longer wanted. - */ - fde->events &= (~events); - if(fde->events == 0) { - fdevent_plist_remove(fde); - fde->state &= (~FDE_PENDING); - } - } -} - -void fdevent_add(fdevent *fde, unsigned events) -{ - fdevent_set( - fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK)); -} - -void fdevent_del(fdevent *fde, unsigned events) -{ - fdevent_set( - fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK))); -} - -void fdevent_loop() -{ - fdevent *fde; - - for(;;) { -#if DEBUG - fprintf(stderr,"--- ---- waiting for events\n"); -#endif - fdevent_process(); - - while((fde = fdevent_plist_dequeue())) { - unsigned events = fde->events; - fde->events = 0; - fde->state &= (~FDE_PENDING); - dump_fde(fde, "callback"); - fde->func(fde->fd, events, fde->arg); - } - } -} - diff --git a/libcutils/hashmap.c b/libcutils/hashmap.c deleted file mode 100644 index e29bc2461cc93ac6c0f713e23dbbdf241e9c1cd0..0000000000000000000000000000000000000000 --- a/libcutils/hashmap.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/hashmap.h> -#include <assert.h> -#include <errno.h> -#include <cutils/threads.h> -#include <stdlib.h> -#include <string.h> -#include <stdbool.h> -#include <sys/types.h> - -typedef struct Entry Entry; -struct Entry { - void* key; - int hash; - void* value; - Entry* next; -}; - -struct Hashmap { - Entry** buckets; - size_t bucketCount; - int (*hash)(void* key); - bool (*equals)(void* keyA, void* keyB); - mutex_t lock; - size_t size; -}; - -Hashmap* hashmapCreate(size_t initialCapacity, - int (*hash)(void* key), bool (*equals)(void* keyA, void* keyB)) { - assert(hash != NULL); - assert(equals != NULL); - - Hashmap* map = malloc(sizeof(Hashmap)); - if (map == NULL) { - return NULL; - } - - // 0.75 load factor. - size_t minimumBucketCount = initialCapacity * 4 / 3; - map->bucketCount = 1; - while (map->bucketCount <= minimumBucketCount) { - // Bucket count must be power of 2. - map->bucketCount <<= 1; - } - - map->buckets = calloc(map->bucketCount, sizeof(Entry*)); - if (map->buckets == NULL) { - free(map); - return NULL; - } - - map->size = 0; - - map->hash = hash; - map->equals = equals; - - mutex_init(&map->lock); - - return map; -} - -/** - * Hashes the given key. - */ -static inline int hashKey(Hashmap* map, void* key) { - int h = map->hash(key); - - // We apply this secondary hashing discovered by Doug Lea to defend - // against bad hashes. - h += ~(h << 9); - h ^= (((unsigned int) h) >> 14); - h += (h << 4); - h ^= (((unsigned int) h) >> 10); - - return h; -} - -size_t hashmapSize(Hashmap* map) { - return map->size; -} - -static inline size_t calculateIndex(size_t bucketCount, int hash) { - return ((size_t) hash) & (bucketCount - 1); -} - -static void expandIfNecessary(Hashmap* map) { - // If the load factor exceeds 0.75... - if (map->size > (map->bucketCount * 3 / 4)) { - // Start off with a 0.33 load factor. - size_t newBucketCount = map->bucketCount << 1; - Entry** newBuckets = calloc(newBucketCount, sizeof(Entry*)); - if (newBuckets == NULL) { - // Abort expansion. - return; - } - - // Move over existing entries. - size_t i; - for (i = 0; i < map->bucketCount; i++) { - Entry* entry = map->buckets[i]; - while (entry != NULL) { - Entry* next = entry->next; - size_t index = calculateIndex(newBucketCount, entry->hash); - entry->next = newBuckets[index]; - newBuckets[index] = entry; - entry = next; - } - } - - // Copy over internals. - free(map->buckets); - map->buckets = newBuckets; - map->bucketCount = newBucketCount; - } -} - -void hashmapLock(Hashmap* map) { - mutex_lock(&map->lock); -} - -void hashmapUnlock(Hashmap* map) { - mutex_unlock(&map->lock); -} - -void hashmapFree(Hashmap* map) { - size_t i; - for (i = 0; i < map->bucketCount; i++) { - Entry* entry = map->buckets[i]; - while (entry != NULL) { - Entry* next = entry->next; - free(entry); - entry = next; - } - } - free(map->buckets); - mutex_destroy(&map->lock); - free(map); -} - -int hashmapHash(void* key, size_t keySize) { - int h = keySize; - char* data = (char*) key; - size_t i; - for (i = 0; i < keySize; i++) { - h = h * 31 + *data; - data++; - } - return h; -} - -static Entry* createEntry(void* key, int hash, void* value) { - Entry* entry = malloc(sizeof(Entry)); - if (entry == NULL) { - return NULL; - } - entry->key = key; - entry->hash = hash; - entry->value = value; - entry->next = NULL; - return entry; -} - -static inline bool equalKeys(void* keyA, int hashA, void* keyB, int hashB, - bool (*equals)(void*, void*)) { - if (keyA == keyB) { - return true; - } - if (hashA != hashB) { - return false; - } - return equals(keyA, keyB); -} - -void* hashmapPut(Hashmap* map, void* key, void* value) { - int hash = hashKey(map, key); - size_t index = calculateIndex(map->bucketCount, hash); - - Entry** p = &(map->buckets[index]); - while (true) { - Entry* current = *p; - - // Add a new entry. - if (current == NULL) { - *p = createEntry(key, hash, value); - if (*p == NULL) { - errno = ENOMEM; - return NULL; - } - map->size++; - expandIfNecessary(map); - return NULL; - } - - // Replace existing entry. - if (equalKeys(current->key, current->hash, key, hash, map->equals)) { - void* oldValue = current->value; - current->value = value; - return oldValue; - } - - // Move to next entry. - p = ¤t->next; - } -} - -void* hashmapGet(Hashmap* map, void* key) { - int hash = hashKey(map, key); - size_t index = calculateIndex(map->bucketCount, hash); - - Entry* entry = map->buckets[index]; - while (entry != NULL) { - if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) { - return entry->value; - } - entry = entry->next; - } - - return NULL; -} - -bool hashmapContainsKey(Hashmap* map, void* key) { - int hash = hashKey(map, key); - size_t index = calculateIndex(map->bucketCount, hash); - - Entry* entry = map->buckets[index]; - while (entry != NULL) { - if (equalKeys(entry->key, entry->hash, key, hash, map->equals)) { - return true; - } - entry = entry->next; - } - - return false; -} - -void* hashmapMemoize(Hashmap* map, void* key, - void* (*initialValue)(void* key, void* context), void* context) { - int hash = hashKey(map, key); - size_t index = calculateIndex(map->bucketCount, hash); - - Entry** p = &(map->buckets[index]); - while (true) { - Entry* current = *p; - - // Add a new entry. - if (current == NULL) { - *p = createEntry(key, hash, NULL); - if (*p == NULL) { - errno = ENOMEM; - return NULL; - } - void* value = initialValue(key, context); - (*p)->value = value; - map->size++; - expandIfNecessary(map); - return value; - } - - // Return existing value. - if (equalKeys(current->key, current->hash, key, hash, map->equals)) { - return current->value; - } - - // Move to next entry. - p = ¤t->next; - } -} - -void* hashmapRemove(Hashmap* map, void* key) { - int hash = hashKey(map, key); - size_t index = calculateIndex(map->bucketCount, hash); - - // Pointer to the current entry. - Entry** p = &(map->buckets[index]); - Entry* current; - while ((current = *p) != NULL) { - if (equalKeys(current->key, current->hash, key, hash, map->equals)) { - void* value = current->value; - *p = current->next; - free(current); - map->size--; - return value; - } - - p = ¤t->next; - } - - return NULL; -} - -void hashmapForEach(Hashmap* map, - bool (*callback)(void* key, void* value, void* context), - void* context) { - size_t i; - for (i = 0; i < map->bucketCount; i++) { - Entry* entry = map->buckets[i]; - while (entry != NULL) { - if (!callback(entry->key, entry->value, context)) { - return; - } - entry = entry->next; - } - } -} - -size_t hashmapCurrentCapacity(Hashmap* map) { - size_t bucketCount = map->bucketCount; - return bucketCount * 3 / 4; -} - -size_t hashmapCountCollisions(Hashmap* map) { - size_t collisions = 0; - size_t i; - for (i = 0; i < map->bucketCount; i++) { - Entry* entry = map->buckets[i]; - while (entry != NULL) { - if (entry->next != NULL) { - collisions++; - } - entry = entry->next; - } - } - return collisions; -} - -int hashmapIntHash(void* key) { - // Return the key value itself. - return *((int*) key); -} - -bool hashmapIntEquals(void* keyA, void* keyB) { - int a = *((int*) keyA); - int b = *((int*) keyB); - return a == b; -} diff --git a/libcutils/load_file.c b/libcutils/load_file.c deleted file mode 100644 index 99f2965aec63076959be95c0992deee40ec647f6..0000000000000000000000000000000000000000 --- a/libcutils/load_file.c +++ /dev/null @@ -1,51 +0,0 @@ -/* libs/cutils/load_file.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> - -void *load_file(const char *fn, unsigned *_sz) -{ - char *data; - int sz; - int fd; - - data = 0; - fd = open(fn, O_RDONLY); - if(fd < 0) return 0; - - sz = lseek(fd, 0, SEEK_END); - if(sz < 0) goto oops; - - if(lseek(fd, 0, SEEK_SET) != 0) goto oops; - - data = (char*) malloc(sz + 1); - if(data == 0) goto oops; - - if(read(fd, data, sz) != sz) goto oops; - close(fd); - data[sz] = 0; - - if(_sz) *_sz = sz; - return data; - -oops: - close(fd); - if(data != 0) free(data); - return 0; -} diff --git a/libcutils/loghack.h b/libcutils/loghack.h deleted file mode 100644 index 2bfffe4ec6b39842352efebd8ae4958b9c236302..0000000000000000000000000000000000000000 --- a/libcutils/loghack.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * This is a temporary hack to enable logging from cutils. - */ - -#ifndef _CUTILS_LOGHACK_H -#define _CUTILS_LOGHACK_H - -#ifdef HAVE_ANDROID_OS -#include <cutils/log.h> -#else -#include <stdio.h> -#define LOG(level, ...) \ - ((void)printf("cutils:" level "/" LOG_TAG ": " __VA_ARGS__)) -#define LOGV(...) LOG("V", __VA_ARGS__) -#define LOGD(...) LOG("D", __VA_ARGS__) -#define LOGI(...) LOG("I", __VA_ARGS__) -#define LOGW(...) LOG("W", __VA_ARGS__) -#define LOGE(...) LOG("E", __VA_ARGS__) -#define LOG_ALWAYS_FATAL(...) do { LOGE(__VA_ARGS__); exit(1); } while (0) -#endif - -#endif // _CUTILS_LOGHACK_H diff --git a/libcutils/memory.c b/libcutils/memory.c deleted file mode 100644 index ef6c7e6636c47bfa9622c8ec4b0c8a583690d391..0000000000000000000000000000000000000000 --- a/libcutils/memory.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/memory.h> - -void android_memset16(uint16_t* dst, uint16_t value, size_t size) -{ - size >>= 1; - while (size--) { - *dst++ = value; - } -} - -void android_memset32(uint32_t* dst, uint32_t value, size_t size) -{ - size >>= 2; - while (size--) { - *dst++ = value; - } -} - -#if !HAVE_STRLCPY -/* - * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> - * - * 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 THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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. - */ - -#include <sys/types.h> -#include <string.h> - -/* Implementation of strlcpy() for platforms that don't already have it. */ - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -size_t -strlcpy(char *dst, const char *src, size_t siz) -{ - char *d = dst; - const char *s = src; - size_t n = siz; - - /* Copy as many bytes as will fit */ - if (n != 0) { - while (--n != 0) { - if ((*d++ = *s++) == '\0') - break; - } - } - - /* Not enough room in dst, add NUL and traverse rest of src */ - if (n == 0) { - if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while (*s++) - ; - } - - return(s - src - 1); /* count does not include NUL */ -} -#endif diff --git a/libcutils/memset32.S b/libcutils/memset32.S deleted file mode 100644 index 4697265636e711c69884c7d40214cd5167c48233..0000000000000000000000000000000000000000 --- a/libcutils/memset32.S +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * memset32.S - * - */ - - .text - .align - - .global android_memset32 - .type android_memset32, %function - .global android_memset16 - .type android_memset16, %function - - /* - * Optimized memset32 and memset16 for ARM. - * - * void android_memset16(uint16_t* dst, uint16_t value, size_t size); - * void android_memset32(uint32_t* dst, uint32_t value, size_t size); - * - */ - -android_memset16: - .fnstart - cmp r2, #1 - bxle lr - - /* expand the data to 32 bits */ - mov r1, r1, lsl #16 - orr r1, r1, r1, lsr #16 - - /* align to 32 bits */ - tst r0, #2 - strneh r1, [r0], #2 - subne r2, r2, #2 - .fnend - -android_memset32: - .fnstart - .save {lr} - str lr, [sp, #-4]! - - /* align the destination to a cache-line */ - mov r12, r1 - mov lr, r1 - rsb r3, r0, #0 - ands r3, r3, #0x1C - beq .Laligned32 - cmp r3, r2 - andhi r3, r2, #0x1C - sub r2, r2, r3 - - /* conditionally writes 0 to 7 words (length in r3) */ - movs r3, r3, lsl #28 - stmcsia r0!, {r1, lr} - stmcsia r0!, {r1, lr} - stmmiia r0!, {r1, lr} - movs r3, r3, lsl #2 - strcs r1, [r0], #4 - -.Laligned32: - mov r3, r1 -1: subs r2, r2, #32 - stmhsia r0!, {r1,r3,r12,lr} - stmhsia r0!, {r1,r3,r12,lr} - bhs 1b - add r2, r2, #32 - - /* conditionally stores 0 to 30 bytes */ - movs r2, r2, lsl #28 - stmcsia r0!, {r1,r3,r12,lr} - stmmiia r0!, {r1,lr} - movs r2, r2, lsl #2 - strcs r1, [r0], #4 - strmih lr, [r0], #2 - - ldr lr, [sp], #4 - bx lr - .fnend diff --git a/libcutils/mq.c b/libcutils/mq.c deleted file mode 100644 index 3b65f1f16d9d152309490fc75cd3fadb4f55c694..0000000000000000000000000000000000000000 --- a/libcutils/mq.c +++ /dev/null @@ -1,1357 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "mq" - -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <sys/socket.h> -#include <sys/types.h> -#include <sys/un.h> -#include <sys/uio.h> - -#include <cutils/array.h> -#include <cutils/hashmap.h> -#include <cutils/selector.h> - -#include "loghack.h" -#include "buffer.h" - -/** Number of dead peers to remember. */ -#define PEER_HISTORY (16) - -typedef struct sockaddr SocketAddress; -typedef struct sockaddr_un UnixAddress; - -/** - * Process/user/group ID. We don't use ucred directly because it's only - * available on Linux. - */ -typedef struct { - pid_t pid; - uid_t uid; - gid_t gid; -} Credentials; - -/** Listens for bytes coming from remote peers. */ -typedef void BytesListener(Credentials credentials, char* bytes, size_t size); - -/** Listens for the deaths of remote peers. */ -typedef void DeathListener(pid_t pid); - -/** Types of packets. */ -typedef enum { - /** Request for a connection to another peer. */ - CONNECTION_REQUEST, - - /** A connection to another peer. */ - CONNECTION, - - /** Reports a failed connection attempt. */ - CONNECTION_ERROR, - - /** A generic packet of bytes. */ - BYTES, -} PacketType; - -typedef enum { - /** Reading a packet header. */ - READING_HEADER, - - /** Waiting for a connection from the master. */ - ACCEPTING_CONNECTION, - - /** Reading bytes. */ - READING_BYTES, -} InputState; - -/** A packet header. */ -// TODO: Use custom headers for master->peer, peer->master, peer->peer. -typedef struct { - PacketType type; - union { - /** Packet size. Used for BYTES. */ - size_t size; - - /** Credentials. Used for CONNECTION and CONNECTION_REQUEST. */ - Credentials credentials; - }; -} Header; - -/** A packet which will be sent to a peer. */ -typedef struct OutgoingPacket OutgoingPacket; -struct OutgoingPacket { - /** Packet header. */ - Header header; - - union { - /** Connection to peer. Used with CONNECTION. */ - int socket; - - /** Buffer of bytes. Used with BYTES. */ - Buffer* bytes; - }; - - /** Frees all resources associated with this packet. */ - void (*free)(OutgoingPacket* packet); - - /** Optional context. */ - void* context; - - /** Next packet in the queue. */ - OutgoingPacket* nextPacket; -}; - -/** Represents a remote peer. */ -typedef struct PeerProxy PeerProxy; - -/** Local peer state. You typically have one peer per process. */ -typedef struct { - /** This peer's PID. */ - pid_t pid; - - /** - * Map from pid to peer proxy. The peer has a peer proxy for each remote - * peer it's connected to. - * - * Acquire mutex before use. - */ - Hashmap* peerProxies; - - /** Manages I/O. */ - Selector* selector; - - /** Used to synchronize operations with the selector thread. */ - pthread_mutex_t mutex; - - /** Is this peer the master? */ - bool master; - - /** Peer proxy for the master. */ - PeerProxy* masterProxy; - - /** Listens for packets from remote peers. */ - BytesListener* onBytes; - - /** Listens for deaths of remote peers. */ - DeathListener* onDeath; - - /** Keeps track of recently dead peers. Requires mutex. */ - pid_t deadPeers[PEER_HISTORY]; - size_t deadPeerCursor; -} Peer; - -struct PeerProxy { - /** Credentials of the remote process. */ - Credentials credentials; - - /** Keeps track of data coming in from the remote peer. */ - InputState inputState; - Buffer* inputBuffer; - PeerProxy* connecting; - - /** File descriptor for this peer. */ - SelectableFd* fd; - - /** - * Queue of packets to be written out to the remote peer. - * - * Requires mutex. - */ - // TODO: Limit queue length. - OutgoingPacket* currentPacket; - OutgoingPacket* lastPacket; - - /** Used to write outgoing header. */ - Buffer outgoingHeader; - - /** True if this is the master's proxy. */ - bool master; - - /** Reference back to the local peer. */ - Peer* peer; - - /** - * Used in master only. Maps this peer proxy to other peer proxies to - * which the peer has been connected to. Maps pid to PeerProxy. Helps - * keep track of which connections we've sent to whom. - */ - Hashmap* connections; -}; - -/** Server socket path. */ -static const char* MASTER_PATH = "/master.peer"; - -/** Credentials of the master peer. */ -static const Credentials MASTER_CREDENTIALS = {0, 0, 0}; - -/** Creates a peer proxy and adds it to the peer proxy map. */ -static PeerProxy* peerProxyCreate(Peer* peer, Credentials credentials); - -/** Sets the non-blocking flag on a descriptor. */ -static void setNonBlocking(int fd) { - int flags; - if ((flags = fcntl(fd, F_GETFL, 0)) < 0) { - LOG_ALWAYS_FATAL("fcntl() error: %s", strerror(errno)); - } - if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) { - LOG_ALWAYS_FATAL("fcntl() error: %s", strerror(errno)); - } -} - -/** Closes a fd and logs a warning if the close fails. */ -static void closeWithWarning(int fd) { - int result = close(fd); - if (result == -1) { - LOGW("close() error: %s", strerror(errno)); - } -} - -/** Hashes pid_t keys. */ -static int pidHash(void* key) { - pid_t* pid = (pid_t*) key; - return (int) (*pid); -} - -/** Compares pid_t keys. */ -static bool pidEquals(void* keyA, void* keyB) { - pid_t* a = (pid_t*) keyA; - pid_t* b = (pid_t*) keyB; - return *a == *b; -} - -/** Gets the master address. Not thread safe. */ -static UnixAddress* getMasterAddress() { - static UnixAddress masterAddress; - static bool initialized = false; - if (initialized == false) { - masterAddress.sun_family = AF_LOCAL; - strcpy(masterAddress.sun_path, MASTER_PATH); - initialized = true; - } - return &masterAddress; -} - -/** Gets exclusive access to the peer for this thread. */ -static void peerLock(Peer* peer) { - pthread_mutex_lock(&peer->mutex); -} - -/** Releases exclusive access to the peer. */ -static void peerUnlock(Peer* peer) { - pthread_mutex_unlock(&peer->mutex); -} - -/** Frees a simple, i.e. header-only, outgoing packet. */ -static void outgoingPacketFree(OutgoingPacket* packet) { - LOGD("Freeing outgoing packet."); - free(packet); -} - -/** - * Prepare to read a new packet from the peer. - */ -static void peerProxyExpectHeader(PeerProxy* peerProxy) { - peerProxy->inputState = READING_HEADER; - bufferPrepareForRead(peerProxy->inputBuffer, sizeof(Header)); -} - -/** Sets up the buffer for the outgoing header. */ -static void peerProxyPrepareOutgoingHeader(PeerProxy* peerProxy) { - peerProxy->outgoingHeader.data - = (char*) &(peerProxy->currentPacket->header); - peerProxy->outgoingHeader.size = sizeof(Header); - bufferPrepareForWrite(&peerProxy->outgoingHeader); -} - -/** Adds a packet to the end of the queue. Callers must have the mutex. */ -static void peerProxyEnqueueOutgoingPacket(PeerProxy* peerProxy, - OutgoingPacket* newPacket) { - newPacket->nextPacket = NULL; // Just in case. - if (peerProxy->currentPacket == NULL) { - // The queue is empty. - peerProxy->currentPacket = newPacket; - peerProxy->lastPacket = newPacket; - - peerProxyPrepareOutgoingHeader(peerProxy); - } else { - peerProxy->lastPacket->nextPacket = newPacket; - } -} - -/** Takes the peer lock and enqueues the given packet. */ -static void peerProxyLockAndEnqueueOutgoingPacket(PeerProxy* peerProxy, - OutgoingPacket* newPacket) { - Peer* peer = peerProxy->peer; - peerLock(peer); - peerProxyEnqueueOutgoingPacket(peerProxy, newPacket); - peerUnlock(peer); -} - -/** - * Frees current packet and moves to the next one. Returns true if there is - * a next packet or false if the queue is empty. - */ -static bool peerProxyNextPacket(PeerProxy* peerProxy) { - Peer* peer = peerProxy->peer; - peerLock(peer); - - OutgoingPacket* current = peerProxy->currentPacket; - - if (current == NULL) { - // The queue is already empty. - peerUnlock(peer); - return false; - } - - OutgoingPacket* next = current->nextPacket; - peerProxy->currentPacket = next; - current->nextPacket = NULL; - current->free(current); - if (next == NULL) { - // The queue is empty. - peerProxy->lastPacket = NULL; - peerUnlock(peer); - return false; - } else { - peerUnlock(peer); - peerProxyPrepareOutgoingHeader(peerProxy); - - // TODO: Start writing next packet? It would reduce the number of - // system calls, but we could also starve other peers. - return true; - } -} - -/** - * Checks whether a peer died recently. - */ -static bool peerIsDead(Peer* peer, pid_t pid) { - size_t i; - for (i = 0; i < PEER_HISTORY; i++) { - pid_t deadPeer = peer->deadPeers[i]; - if (deadPeer == 0) { - return false; - } - if (deadPeer == pid) { - return true; - } - } - return false; -} - -/** - * Cleans up connection information. - */ -static bool peerProxyRemoveConnection(void* key, void* value, void* context) { - PeerProxy* deadPeer = (PeerProxy*) context; - PeerProxy* otherPeer = (PeerProxy*) value; - hashmapRemove(otherPeer->connections, &(deadPeer->credentials.pid)); - return true; -} - -/** - * Called when the peer dies. - */ -static void peerProxyKill(PeerProxy* peerProxy, bool errnoIsSet) { - if (errnoIsSet) { - LOGI("Peer %d died. errno: %s", peerProxy->credentials.pid, - strerror(errno)); - } else { - LOGI("Peer %d died.", peerProxy->credentials.pid); - } - - // If we lost the master, we're up a creek. We can't let this happen. - if (peerProxy->master) { - LOG_ALWAYS_FATAL("Lost connection to master."); - } - - Peer* localPeer = peerProxy->peer; - pid_t pid = peerProxy->credentials.pid; - - peerLock(localPeer); - - // Remember for awhile that the peer died. - localPeer->deadPeers[localPeer->deadPeerCursor] - = peerProxy->credentials.pid; - localPeer->deadPeerCursor++; - if (localPeer->deadPeerCursor == PEER_HISTORY) { - localPeer->deadPeerCursor = 0; - } - - // Remove from peer map. - hashmapRemove(localPeer->peerProxies, &pid); - - // External threads can no longer get to this peer proxy, so we don't - // need the lock anymore. - peerUnlock(localPeer); - - // Remove the fd from the selector. - if (peerProxy->fd != NULL) { - peerProxy->fd->remove = true; - } - - // Clear outgoing packet queue. - while (peerProxyNextPacket(peerProxy)) {} - - bufferFree(peerProxy->inputBuffer); - - // This only applies to the master. - if (peerProxy->connections != NULL) { - // We can't leave these other maps pointing to freed memory. - hashmapForEach(peerProxy->connections, &peerProxyRemoveConnection, - peerProxy); - hashmapFree(peerProxy->connections); - } - - // Invoke death listener. - localPeer->onDeath(pid); - - // Free the peer proxy itself. - free(peerProxy); -} - -static void peerProxyHandleError(PeerProxy* peerProxy, char* functionName) { - if (errno == EINTR) { - // Log interruptions but otherwise ignore them. - LOGW("%s() interrupted.", functionName); - } else if (errno == EAGAIN) { - LOGD("EWOULDBLOCK"); - // Ignore. - } else { - LOGW("Error returned by %s().", functionName); - peerProxyKill(peerProxy, true); - } -} - -/** - * Buffers output sent to a peer. May be called multiple times until the entire - * buffer is filled. Returns true when the buffer is empty. - */ -static bool peerProxyWriteFromBuffer(PeerProxy* peerProxy, Buffer* outgoing) { - ssize_t size = bufferWrite(outgoing, peerProxy->fd->fd); - if (size < 0) { - peerProxyHandleError(peerProxy, "write"); - return false; - } else { - return bufferWriteComplete(outgoing); - } -} - -/** Writes packet bytes to peer. */ -static void peerProxyWriteBytes(PeerProxy* peerProxy) { - Buffer* buffer = peerProxy->currentPacket->bytes; - if (peerProxyWriteFromBuffer(peerProxy, buffer)) { - LOGD("Bytes written."); - peerProxyNextPacket(peerProxy); - } -} - -/** Sends a socket to the peer. */ -static void peerProxyWriteConnection(PeerProxy* peerProxy) { - int socket = peerProxy->currentPacket->socket; - - // Why does sending and receiving fds have to be such a PITA? - struct msghdr msg; - struct iovec iov[1]; - - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(int))]; - } control_un; - - struct cmsghdr *cmptr; - - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - cmptr = CMSG_FIRSTHDR(&msg); - cmptr->cmsg_len = CMSG_LEN(sizeof(int)); - cmptr->cmsg_level = SOL_SOCKET; - cmptr->cmsg_type = SCM_RIGHTS; - - // Store the socket in the message. - *((int *) CMSG_DATA(cmptr)) = peerProxy->currentPacket->socket; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - iov[0].iov_base = ""; - iov[0].iov_len = 1; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - ssize_t result = sendmsg(peerProxy->fd->fd, &msg, 0); - - if (result < 0) { - peerProxyHandleError(peerProxy, "sendmsg"); - } else { - // Success. Queue up the next packet. - peerProxyNextPacket(peerProxy); - - } -} - -/** - * Writes some outgoing data. - */ -static void peerProxyWrite(SelectableFd* fd) { - // TODO: Try to write header and body with one system call. - - PeerProxy* peerProxy = (PeerProxy*) fd->data; - OutgoingPacket* current = peerProxy->currentPacket; - - if (current == NULL) { - // We have nothing left to write. - return; - } - - // Write the header. - Buffer* outgoingHeader = &peerProxy->outgoingHeader; - bool headerWritten = bufferWriteComplete(outgoingHeader); - if (!headerWritten) { - LOGD("Writing header..."); - headerWritten = peerProxyWriteFromBuffer(peerProxy, outgoingHeader); - if (headerWritten) { - LOGD("Header written."); - } - } - - // Write body. - if (headerWritten) { - PacketType type = current->header.type; - switch (type) { - case CONNECTION: - peerProxyWriteConnection(peerProxy); - break; - case BYTES: - peerProxyWriteBytes(peerProxy); - break; - case CONNECTION_REQUEST: - case CONNECTION_ERROR: - // These packets consist solely of a header. - peerProxyNextPacket(peerProxy); - break; - default: - LOG_ALWAYS_FATAL("Unknown packet type: %d", type); - } - } -} - -/** - * Sets up a peer proxy's fd before we try to select() it. - */ -static void peerProxyBeforeSelect(SelectableFd* fd) { - LOGD("Before select..."); - - PeerProxy* peerProxy = (PeerProxy*) fd->data; - - peerLock(peerProxy->peer); - bool hasPackets = peerProxy->currentPacket != NULL; - peerUnlock(peerProxy->peer); - - if (hasPackets) { - LOGD("Packets found. Setting onWritable()."); - - fd->onWritable = &peerProxyWrite; - } else { - // We have nothing to write. - fd->onWritable = NULL; - } -} - -/** Prepare to read bytes from the peer. */ -static void peerProxyExpectBytes(PeerProxy* peerProxy, Header* header) { - LOGD("Expecting %d bytes.", header->size); - - peerProxy->inputState = READING_BYTES; - if (bufferPrepareForRead(peerProxy->inputBuffer, header->size) == -1) { - LOGW("Couldn't allocate memory for incoming data. Size: %u", - (unsigned int) header->size); - - // TODO: Ignore the packet and log a warning? - peerProxyKill(peerProxy, false); - } -} - -/** - * Gets a peer proxy for the given ID. Creates a peer proxy if necessary. - * Sends a connection request to the master if desired. - * - * Returns NULL if an error occurs. Sets errno to EHOSTDOWN if the peer died - * or ENOMEM if memory couldn't be allocated. - */ -static PeerProxy* peerProxyGetOrCreate(Peer* peer, pid_t pid, - bool requestConnection) { - if (pid == peer->pid) { - errno = EINVAL; - return NULL; - } - - if (peerIsDead(peer, pid)) { - errno = EHOSTDOWN; - return NULL; - } - - PeerProxy* peerProxy = hashmapGet(peer->peerProxies, &pid); - if (peerProxy != NULL) { - return peerProxy; - } - - // If this is the master peer, we already know about all peers. - if (peer->master) { - errno = EHOSTDOWN; - return NULL; - } - - // Try to create a peer proxy. - Credentials credentials; - credentials.pid = pid; - - // Fake gid and uid until we have the real thing. The real creds are - // filled in by masterProxyExpectConnection(). These fake creds will - // never be exposed to the user. - credentials.uid = 0; - credentials.gid = 0; - - // Make sure we can allocate the connection request packet. - OutgoingPacket* packet = NULL; - if (requestConnection) { - packet = calloc(1, sizeof(OutgoingPacket)); - if (packet == NULL) { - errno = ENOMEM; - return NULL; - } - - packet->header.type = CONNECTION_REQUEST; - packet->header.credentials = credentials; - packet->free = &outgoingPacketFree; - } - - peerProxy = peerProxyCreate(peer, credentials); - if (peerProxy == NULL) { - free(packet); - errno = ENOMEM; - return NULL; - } else { - // Send a connection request to the master. - if (requestConnection) { - PeerProxy* masterProxy = peer->masterProxy; - peerProxyEnqueueOutgoingPacket(masterProxy, packet); - } - - return peerProxy; - } -} - -/** - * Switches the master peer proxy into a state where it's waiting for a - * connection from the master. - */ -static void masterProxyExpectConnection(PeerProxy* masterProxy, - Header* header) { - // TODO: Restructure things so we don't need this check. - // Verify that this really is the master. - if (!masterProxy->master) { - LOGW("Non-master process %d tried to send us a connection.", - masterProxy->credentials.pid); - // Kill off the evil peer. - peerProxyKill(masterProxy, false); - return; - } - - masterProxy->inputState = ACCEPTING_CONNECTION; - Peer* localPeer = masterProxy->peer; - - // Create a peer proxy so we have somewhere to stash the creds. - // See if we already have a proxy set up. - pid_t pid = header->credentials.pid; - peerLock(localPeer); - PeerProxy* peerProxy = peerProxyGetOrCreate(localPeer, pid, false); - if (peerProxy == NULL) { - LOGW("Peer proxy creation failed: %s", strerror(errno)); - } else { - // Fill in full credentials. - peerProxy->credentials = header->credentials; - } - peerUnlock(localPeer); - - // Keep track of which peer proxy we're accepting a connection for. - masterProxy->connecting = peerProxy; -} - -/** - * Reads input from a peer process. - */ -static void peerProxyRead(SelectableFd* fd); - -/** Sets up fd callbacks. */ -static void peerProxySetFd(PeerProxy* peerProxy, SelectableFd* fd) { - peerProxy->fd = fd; - fd->data = peerProxy; - fd->onReadable = &peerProxyRead; - fd->beforeSelect = &peerProxyBeforeSelect; - - // Make the socket non-blocking. - setNonBlocking(fd->fd); -} - -/** - * Accepts a connection sent by the master proxy. - */ -static void masterProxyAcceptConnection(PeerProxy* masterProxy) { - struct msghdr msg; - struct iovec iov[1]; - ssize_t size; - char ignored; - int incomingFd; - - // TODO: Reuse code which writes the connection. Who the heck designed - // this API anyway? - union { - struct cmsghdr cm; - char control[CMSG_SPACE(sizeof(int))]; - } control_un; - struct cmsghdr *cmptr; - msg.msg_control = control_un.control; - msg.msg_controllen = sizeof(control_un.control); - - msg.msg_name = NULL; - msg.msg_namelen = 0; - - // We sent 1 byte of data so we can detect EOF. - iov[0].iov_base = &ignored; - iov[0].iov_len = 1; - msg.msg_iov = iov; - msg.msg_iovlen = 1; - - size = recvmsg(masterProxy->fd->fd, &msg, 0); - if (size < 0) { - if (errno == EINTR) { - // Log interruptions but otherwise ignore them. - LOGW("recvmsg() interrupted."); - return; - } else if (errno == EAGAIN) { - // Keep waiting for the connection. - return; - } else { - LOG_ALWAYS_FATAL("Error reading connection from master: %s", - strerror(errno)); - } - } else if (size == 0) { - // EOF. - LOG_ALWAYS_FATAL("Received EOF from master."); - } - - // Extract fd from message. - if ((cmptr = CMSG_FIRSTHDR(&msg)) != NULL - && cmptr->cmsg_len == CMSG_LEN(sizeof(int))) { - if (cmptr->cmsg_level != SOL_SOCKET) { - LOG_ALWAYS_FATAL("Expected SOL_SOCKET."); - } - if (cmptr->cmsg_type != SCM_RIGHTS) { - LOG_ALWAYS_FATAL("Expected SCM_RIGHTS."); - } - incomingFd = *((int*) CMSG_DATA(cmptr)); - } else { - LOG_ALWAYS_FATAL("Expected fd."); - } - - // The peer proxy this connection is for. - PeerProxy* peerProxy = masterProxy->connecting; - if (peerProxy == NULL) { - LOGW("Received connection for unknown peer."); - closeWithWarning(incomingFd); - } else { - Peer* peer = masterProxy->peer; - - SelectableFd* selectableFd = selectorAdd(peer->selector, incomingFd); - if (selectableFd == NULL) { - LOGW("Error adding fd to selector for %d.", - peerProxy->credentials.pid); - closeWithWarning(incomingFd); - peerProxyKill(peerProxy, false); - } - - peerProxySetFd(peerProxy, selectableFd); - } - - peerProxyExpectHeader(masterProxy); -} - -/** - * Frees an outgoing packet containing a connection. - */ -static void outgoingPacketFreeSocket(OutgoingPacket* packet) { - closeWithWarning(packet->socket); - outgoingPacketFree(packet); -} - -/** - * Connects two known peers. - */ -static void masterConnectPeers(PeerProxy* peerA, PeerProxy* peerB) { - int sockets[2]; - int result = socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets); - if (result == -1) { - LOGW("socketpair() error: %s", strerror(errno)); - // TODO: Send CONNECTION_FAILED packets to peers. - return; - } - - OutgoingPacket* packetA = calloc(1, sizeof(OutgoingPacket)); - OutgoingPacket* packetB = calloc(1, sizeof(OutgoingPacket)); - if (packetA == NULL || packetB == NULL) { - free(packetA); - free(packetB); - LOGW("malloc() error. Failed to tell process %d that process %d is" - " dead.", peerA->credentials.pid, peerB->credentials.pid); - return; - } - - packetA->header.type = CONNECTION; - packetB->header.type = CONNECTION; - - packetA->header.credentials = peerB->credentials; - packetB->header.credentials = peerA->credentials; - - packetA->socket = sockets[0]; - packetB->socket = sockets[1]; - - packetA->free = &outgoingPacketFreeSocket; - packetB->free = &outgoingPacketFreeSocket; - - peerLock(peerA->peer); - peerProxyEnqueueOutgoingPacket(peerA, packetA); - peerProxyEnqueueOutgoingPacket(peerB, packetB); - peerUnlock(peerA->peer); -} - -/** - * Informs a peer that the peer they're trying to connect to couldn't be - * found. - */ -static void masterReportConnectionError(PeerProxy* peerProxy, - Credentials credentials) { - OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket)); - if (packet == NULL) { - LOGW("malloc() error. Failed to tell process %d that process %d is" - " dead.", peerProxy->credentials.pid, credentials.pid); - return; - } - - packet->header.type = CONNECTION_ERROR; - packet->header.credentials = credentials; - packet->free = &outgoingPacketFree; - - peerProxyLockAndEnqueueOutgoingPacket(peerProxy, packet); -} - -/** - * Handles a request to be connected to another peer. - */ -static void masterHandleConnectionRequest(PeerProxy* peerProxy, - Header* header) { - Peer* master = peerProxy->peer; - pid_t targetPid = header->credentials.pid; - if (!hashmapContainsKey(peerProxy->connections, &targetPid)) { - // We haven't connected these peers yet. - PeerProxy* targetPeer - = (PeerProxy*) hashmapGet(master->peerProxies, &targetPid); - if (targetPeer == NULL) { - // Unknown process. - masterReportConnectionError(peerProxy, header->credentials); - } else { - masterConnectPeers(peerProxy, targetPeer); - } - } - - // This packet is complete. Get ready for the next one. - peerProxyExpectHeader(peerProxy); -} - -/** - * The master told us this peer is dead. - */ -static void masterProxyHandleConnectionError(PeerProxy* masterProxy, - Header* header) { - Peer* peer = masterProxy->peer; - - // Look up the peer proxy. - pid_t pid = header->credentials.pid; - PeerProxy* peerProxy = NULL; - peerLock(peer); - peerProxy = hashmapGet(peer->peerProxies, &pid); - peerUnlock(peer); - - if (peerProxy != NULL) { - LOGI("Couldn't connect to %d.", pid); - peerProxyKill(peerProxy, false); - } else { - LOGW("Peer proxy for %d not found. This shouldn't happen.", pid); - } - - peerProxyExpectHeader(masterProxy); -} - -/** - * Handles a packet header. - */ -static void peerProxyHandleHeader(PeerProxy* peerProxy, Header* header) { - switch (header->type) { - case CONNECTION_REQUEST: - masterHandleConnectionRequest(peerProxy, header); - break; - case CONNECTION: - masterProxyExpectConnection(peerProxy, header); - break; - case CONNECTION_ERROR: - masterProxyHandleConnectionError(peerProxy, header); - break; - case BYTES: - peerProxyExpectBytes(peerProxy, header); - break; - default: - LOGW("Invalid packet type from %d: %d", peerProxy->credentials.pid, - header->type); - peerProxyKill(peerProxy, false); - } -} - -/** - * Buffers input sent by peer. May be called multiple times until the entire - * buffer is filled. Returns true when the buffer is full. - */ -static bool peerProxyBufferInput(PeerProxy* peerProxy) { - Buffer* in = peerProxy->inputBuffer; - ssize_t size = bufferRead(in, peerProxy->fd->fd); - if (size < 0) { - peerProxyHandleError(peerProxy, "read"); - return false; - } else if (size == 0) { - // EOF. - LOGI("EOF"); - peerProxyKill(peerProxy, false); - return false; - } else if (bufferReadComplete(in)) { - // We're done! - return true; - } else { - // Continue reading. - return false; - } -} - -/** - * Reads input from a peer process. - */ -static void peerProxyRead(SelectableFd* fd) { - LOGD("Reading..."); - PeerProxy* peerProxy = (PeerProxy*) fd->data; - int state = peerProxy->inputState; - Buffer* in = peerProxy->inputBuffer; - switch (state) { - case READING_HEADER: - if (peerProxyBufferInput(peerProxy)) { - LOGD("Header read."); - // We've read the complete header. - Header* header = (Header*) in->data; - peerProxyHandleHeader(peerProxy, header); - } - break; - case READING_BYTES: - LOGD("Reading bytes..."); - if (peerProxyBufferInput(peerProxy)) { - LOGD("Bytes read."); - // We have the complete packet. Notify bytes listener. - peerProxy->peer->onBytes(peerProxy->credentials, - in->data, in->size); - - // Get ready for the next packet. - peerProxyExpectHeader(peerProxy); - } - break; - case ACCEPTING_CONNECTION: - masterProxyAcceptConnection(peerProxy); - break; - default: - LOG_ALWAYS_FATAL("Unknown state: %d", state); - } -} - -static PeerProxy* peerProxyCreate(Peer* peer, Credentials credentials) { - PeerProxy* peerProxy = calloc(1, sizeof(PeerProxy)); - if (peerProxy == NULL) { - return NULL; - } - - peerProxy->inputBuffer = bufferCreate(sizeof(Header)); - if (peerProxy->inputBuffer == NULL) { - free(peerProxy); - return NULL; - } - - peerProxy->peer = peer; - peerProxy->credentials = credentials; - - // Initial state == expecting a header. - peerProxyExpectHeader(peerProxy); - - // Add this proxy to the map. Make sure the key points to the stable memory - // inside of the peer proxy itself. - pid_t* pid = &(peerProxy->credentials.pid); - hashmapPut(peer->peerProxies, pid, peerProxy); - return peerProxy; -} - -/** Accepts a connection to the master peer. */ -static void masterAcceptConnection(SelectableFd* listenerFd) { - // Accept connection. - int socket = accept(listenerFd->fd, NULL, NULL); - if (socket == -1) { - LOGW("accept() error: %s", strerror(errno)); - return; - } - - LOGD("Accepted connection as fd %d.", socket); - - // Get credentials. - Credentials credentials; - struct ucred ucredentials; - socklen_t credentialsSize = sizeof(struct ucred); - int result = getsockopt(socket, SOL_SOCKET, SO_PEERCRED, - &ucredentials, &credentialsSize); - // We might want to verify credentialsSize. - if (result == -1) { - LOGW("getsockopt() error: %s", strerror(errno)); - closeWithWarning(socket); - return; - } - - // Copy values into our own structure so we know we have the types right. - credentials.pid = ucredentials.pid; - credentials.uid = ucredentials.uid; - credentials.gid = ucredentials.gid; - - LOGI("Accepted connection from process %d.", credentials.pid); - - Peer* masterPeer = (Peer*) listenerFd->data; - - peerLock(masterPeer); - - // Make sure we don't already have a connection from that process. - PeerProxy* peerProxy - = hashmapGet(masterPeer->peerProxies, &credentials.pid); - if (peerProxy != NULL) { - peerUnlock(masterPeer); - LOGW("Alread connected to process %d.", credentials.pid); - closeWithWarning(socket); - return; - } - - // Add connection to the selector. - SelectableFd* socketFd = selectorAdd(masterPeer->selector, socket); - if (socketFd == NULL) { - peerUnlock(masterPeer); - LOGW("malloc() failed."); - closeWithWarning(socket); - return; - } - - // Create a peer proxy. - peerProxy = peerProxyCreate(masterPeer, credentials); - peerUnlock(masterPeer); - if (peerProxy == NULL) { - LOGW("malloc() failed."); - socketFd->remove = true; - closeWithWarning(socket); - } - peerProxy->connections = hashmapCreate(10, &pidHash, &pidEquals); - peerProxySetFd(peerProxy, socketFd); -} - -/** - * Creates the local peer. - */ -static Peer* peerCreate() { - Peer* peer = calloc(1, sizeof(Peer)); - if (peer == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - peer->peerProxies = hashmapCreate(10, &pidHash, &pidEquals); - peer->selector = selectorCreate(); - - pthread_mutexattr_t attributes; - if (pthread_mutexattr_init(&attributes) != 0) { - LOG_ALWAYS_FATAL("pthread_mutexattr_init() error."); - } - if (pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE) != 0) { - LOG_ALWAYS_FATAL("pthread_mutexattr_settype() error."); - } - if (pthread_mutex_init(&peer->mutex, &attributes) != 0) { - LOG_ALWAYS_FATAL("pthread_mutex_init() error."); - } - - peer->pid = getpid(); - return peer; -} - -/** The local peer. */ -static Peer* localPeer; - -/** Frees a packet of bytes. */ -static void outgoingPacketFreeBytes(OutgoingPacket* packet) { - LOGD("Freeing outgoing packet."); - bufferFree(packet->bytes); - free(packet); -} - -/** - * Sends a packet of bytes to a remote peer. Returns 0 on success. - * - * Returns -1 if an error occurs. Sets errno to ENOMEM if memory couldn't be - * allocated. Sets errno to EHOSTDOWN if the peer died recently. Sets errno - * to EINVAL if pid is the same as the local pid. - */ -int peerSendBytes(pid_t pid, const char* bytes, size_t size) { - Peer* peer = localPeer; - assert(peer != NULL); - - OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket)); - if (packet == NULL) { - errno = ENOMEM; - return -1; - } - - Buffer* copy = bufferCreate(size); - if (copy == NULL) { - free(packet); - errno = ENOMEM; - return -1; - } - - // Copy data. - memcpy(copy->data, bytes, size); - copy->size = size; - - packet->bytes = copy; - packet->header.type = BYTES; - packet->header.size = size; - packet->free = outgoingPacketFreeBytes; - bufferPrepareForWrite(packet->bytes); - - peerLock(peer); - - PeerProxy* peerProxy = peerProxyGetOrCreate(peer, pid, true); - if (peerProxy == NULL) { - // The peer is already dead or we couldn't alloc memory. Either way, - // errno is set. - peerUnlock(peer); - packet->free(packet); - return -1; - } else { - peerProxyEnqueueOutgoingPacket(peerProxy, packet); - peerUnlock(peer); - selectorWakeUp(peer->selector); - return 0; - } -} - -/** Keeps track of how to free shared bytes. */ -typedef struct { - void (*free)(void* context); - void* context; -} SharedBytesFreer; - -/** Frees shared bytes. */ -static void outgoingPacketFreeSharedBytes(OutgoingPacket* packet) { - SharedBytesFreer* sharedBytesFreer - = (SharedBytesFreer*) packet->context; - sharedBytesFreer->free(sharedBytesFreer->context); - free(sharedBytesFreer); - free(packet); -} - -/** - * Sends a packet of bytes to a remote peer without copying the bytes. Calls - * free() with context after the bytes have been sent. - * - * Returns -1 if an error occurs. Sets errno to ENOMEM if memory couldn't be - * allocated. Sets errno to EHOSTDOWN if the peer died recently. Sets errno - * to EINVAL if pid is the same as the local pid. - */ -int peerSendSharedBytes(pid_t pid, char* bytes, size_t size, - void (*free)(void* context), void* context) { - Peer* peer = localPeer; - assert(peer != NULL); - - OutgoingPacket* packet = calloc(1, sizeof(OutgoingPacket)); - if (packet == NULL) { - errno = ENOMEM; - return -1; - } - - Buffer* wrapper = bufferWrap(bytes, size, size); - if (wrapper == NULL) { - free(packet); - errno = ENOMEM; - return -1; - } - - SharedBytesFreer* sharedBytesFreer = malloc(sizeof(SharedBytesFreer)); - if (sharedBytesFreer == NULL) { - free(packet); - free(wrapper); - errno = ENOMEM; - return -1; - } - sharedBytesFreer->free = free; - sharedBytesFreer->context = context; - - packet->bytes = wrapper; - packet->context = sharedBytesFreer; - packet->header.type = BYTES; - packet->header.size = size; - packet->free = &outgoingPacketFreeSharedBytes; - bufferPrepareForWrite(packet->bytes); - - peerLock(peer); - - PeerProxy* peerProxy = peerProxyGetOrCreate(peer, pid, true); - if (peerProxy == NULL) { - // The peer is already dead or we couldn't alloc memory. Either way, - // errno is set. - peerUnlock(peer); - packet->free(packet); - return -1; - } else { - peerProxyEnqueueOutgoingPacket(peerProxy, packet); - peerUnlock(peer); - selectorWakeUp(peer->selector); - return 0; - } -} - -/** - * Starts the master peer. The master peer differs from other peers in that - * it is responsible for connecting the other peers. You can only have one - * master peer. - * - * Goes into an I/O loop and does not return. - */ -void masterPeerInitialize(BytesListener* bytesListener, - DeathListener* deathListener) { - // Create and bind socket. - int listenerSocket = socket(AF_LOCAL, SOCK_STREAM, 0); - if (listenerSocket == -1) { - LOG_ALWAYS_FATAL("socket() error: %s", strerror(errno)); - } - unlink(MASTER_PATH); - int result = bind(listenerSocket, (SocketAddress*) getMasterAddress(), - sizeof(UnixAddress)); - if (result == -1) { - LOG_ALWAYS_FATAL("bind() error: %s", strerror(errno)); - } - - LOGD("Listener socket: %d", listenerSocket); - - // Queue up to 16 connections. - result = listen(listenerSocket, 16); - if (result != 0) { - LOG_ALWAYS_FATAL("listen() error: %s", strerror(errno)); - } - - // Make socket non-blocking. - setNonBlocking(listenerSocket); - - // Create the peer for this process. Fail if we already have one. - if (localPeer != NULL) { - LOG_ALWAYS_FATAL("Peer is already initialized."); - } - localPeer = peerCreate(); - if (localPeer == NULL) { - LOG_ALWAYS_FATAL("malloc() failed."); - } - localPeer->master = true; - localPeer->onBytes = bytesListener; - localPeer->onDeath = deathListener; - - // Make listener socket selectable. - SelectableFd* listenerFd = selectorAdd(localPeer->selector, listenerSocket); - if (listenerFd == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - listenerFd->data = localPeer; - listenerFd->onReadable = &masterAcceptConnection; -} - -/** - * Starts a local peer. - * - * Goes into an I/O loop and does not return. - */ -void peerInitialize(BytesListener* bytesListener, - DeathListener* deathListener) { - // Connect to master peer. - int masterSocket = socket(AF_LOCAL, SOCK_STREAM, 0); - if (masterSocket == -1) { - LOG_ALWAYS_FATAL("socket() error: %s", strerror(errno)); - } - int result = connect(masterSocket, (SocketAddress*) getMasterAddress(), - sizeof(UnixAddress)); - if (result != 0) { - LOG_ALWAYS_FATAL("connect() error: %s", strerror(errno)); - } - - // Create the peer for this process. Fail if we already have one. - if (localPeer != NULL) { - LOG_ALWAYS_FATAL("Peer is already initialized."); - } - localPeer = peerCreate(); - if (localPeer == NULL) { - LOG_ALWAYS_FATAL("malloc() failed."); - } - localPeer->onBytes = bytesListener; - localPeer->onDeath = deathListener; - - // Make connection selectable. - SelectableFd* masterFd = selectorAdd(localPeer->selector, masterSocket); - if (masterFd == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - - // Create a peer proxy for the master peer. - PeerProxy* masterProxy = peerProxyCreate(localPeer, MASTER_CREDENTIALS); - if (masterProxy == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - peerProxySetFd(masterProxy, masterFd); - masterProxy->master = true; - localPeer->masterProxy = masterProxy; -} - -/** Starts the master peer I/O loop. Doesn't return. */ -void peerLoop() { - assert(localPeer != NULL); - - // Start selector. - selectorLoop(localPeer->selector); -} - diff --git a/libcutils/mspace.c b/libcutils/mspace.c deleted file mode 100644 index 8fd5de77de850144d6042f91983a2d30894414f1..0000000000000000000000000000000000000000 --- a/libcutils/mspace.c +++ /dev/null @@ -1,246 +0,0 @@ -/* Copyright 2006 The Android Open Source Project */ - -/* A wrapper file for dlmalloc.c that compiles in the - * mspace_*() functions, which provide an interface for - * creating multiple heaps. - */ -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> -#include <stdint.h> -#include <sys/ioctl.h> - -#include <cutils/ashmem.h> - -/* It's a pain getting the mallinfo stuff to work - * with Linux, OSX, and klibc, so just turn it off - * for now. - * TODO: make mallinfo work - */ -#define NO_MALLINFO 1 - -/* Allow setting the maximum heap footprint. - */ -#define USE_MAX_ALLOWED_FOOTPRINT 1 - -/* Don't try to trim memory. - * TODO: support this. - */ -#define MORECORE_CANNOT_TRIM 1 - -/* Use mmap()d anonymous memory to guarantee - * that an mspace is contiguous. - * - * create_mspace() won't work right if this is - * defined, so hide the definition of it and - * break any users at build time. - */ -#define USE_CONTIGUOUS_MSPACES 1 -#if USE_CONTIGUOUS_MSPACES -/* This combination of settings forces sys_alloc() - * to always use MORECORE(). It won't expect the - * results to be contiguous, but we'll guarantee - * that they are. - */ -#define HAVE_MMAP 0 -#define HAVE_MORECORE 1 -#define MORECORE_CONTIGUOUS 0 -/* m is always the appropriate local when MORECORE() is called. */ -#define MORECORE(S) contiguous_mspace_morecore(m, S) -#define create_mspace HIDDEN_create_mspace_HIDDEN -#define destroy_mspace HIDDEN_destroy_mspace_HIDDEN -typedef struct malloc_state *mstate0; -static void *contiguous_mspace_morecore(mstate0 m, ssize_t nb); -#endif - -#define MSPACES 1 -#define ONLY_MSPACES 1 -#include "../../../bionic/libc/bionic/dlmalloc.c" - -#ifndef PAGESIZE -#define PAGESIZE mparams.page_size -#endif - -#define ALIGN_UP(p, alignment) \ - (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1)) - -/* A direct copy of dlmalloc_usable_size(), - * which isn't compiled in when ONLY_MSPACES is set. - * The mspace parameter isn't actually necessary, - * but we include it to be consistent with the - * rest of the mspace_*() functions. - */ -size_t mspace_usable_size(mspace _unused, const void* mem) { - if (mem != 0) { - const mchunkptr p = mem2chunk(mem); - if (cinuse(p)) - return chunksize(p) - overhead_for(p); - } - return 0; -} - -#if USE_CONTIGUOUS_MSPACES -#include <sys/mman.h> -#include <limits.h> - -#define CONTIG_STATE_MAGIC 0xf00dd00d -struct mspace_contig_state { - unsigned int magic; - char *brk; - char *top; - mspace m; -}; - -static void *contiguous_mspace_morecore(mstate m, ssize_t nb) { - struct mspace_contig_state *cs; - char *oldbrk; - const unsigned int pagesize = PAGESIZE; - - cs = (struct mspace_contig_state *)((uintptr_t)m & ~(pagesize-1)); - assert(cs->magic == CONTIG_STATE_MAGIC); - assert(cs->m == m); -assert(nb >= 0); //xxx deal with the trim case - - oldbrk = cs->brk; - if (nb > 0) { - /* Break to the first page boundary that satisfies the request. - */ - char *newbrk = (char *)ALIGN_UP(oldbrk + nb, pagesize); - if (newbrk > cs->top) - return CMFAIL; - - /* Update the protection on the underlying memory. - * Pages we've given to dlmalloc are read/write, and - * pages we haven't are not accessable (read or write - * will cause a seg fault). - */ - if (mprotect(cs, newbrk - (char *)cs, PROT_READ | PROT_WRITE) < 0) - return CMFAIL; - if (newbrk != cs->top) { - if (mprotect(newbrk, cs->top - newbrk, PROT_NONE) < 0) - return CMFAIL; - } - - cs->brk = newbrk; - - /* Make sure that dlmalloc will merge this block with the - * initial block that was passed to create_mspace_with_base(). - * We don't care about extern vs. non-extern, so just clear it. - */ - m->seg.sflags &= ~EXTERN_BIT; - } - - return oldbrk; -} - -mspace create_contiguous_mspace_with_name(size_t starting_capacity, - size_t max_capacity, int locked, char const * name) { - int fd, ret; - struct mspace_contig_state *cs; - char buf[ASHMEM_NAME_LEN] = "mspace"; - void *base; - unsigned int pagesize; - mstate m; - - if (starting_capacity > max_capacity) - return (mspace)0; - - init_mparams(); - pagesize = PAGESIZE; - - /* Create the anonymous memory that will back the mspace. - * This reserves all of the virtual address space we could - * ever need. Physical pages will be mapped as the memory - * is touched. - * - * Align max_capacity to a whole page. - */ - max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize); - - if (name) - snprintf(buf, sizeof(buf), "mspace/%s", name); - fd = ashmem_create_region(buf, max_capacity); - if (fd < 0) - return (mspace)0; - - base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); - if (base == MAP_FAILED) - return (mspace)0; - - /* Make sure that base is at the beginning of a page. - */ - assert(((uintptr_t)base & (pagesize-1)) == 0); - - /* Reserve some space for the information that our MORECORE needs. - */ - cs = base; - - /* Create the mspace, pointing to the memory we just reserved. - */ - m = create_mspace_with_base(base + sizeof(*cs), starting_capacity, locked); - if (m == (mspace)0) - goto error; - - /* Make sure that m is in the same page as cs. - */ - assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base); - - /* Find out exactly how much of the memory the mspace - * is using. - */ - cs->brk = m->seg.base + m->seg.size; - cs->top = (char *)base + max_capacity; - assert((char *)base <= cs->brk); - assert(cs->brk <= cs->top); - - /* Prevent access to the memory we haven't handed out yet. - */ - if (cs->brk != cs->top) { - /* mprotect() requires page-aligned arguments, but it's possible - * for cs->brk not to be page-aligned at this point. - */ - char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize); - if (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0) - goto error; - } - - cs->m = m; - cs->magic = CONTIG_STATE_MAGIC; - - return (mspace)m; - -error: - munmap(base, max_capacity); - return (mspace)0; -} - -mspace create_contiguous_mspace(size_t starting_capacity, - size_t max_capacity, int locked) { - return create_contiguous_mspace_with_name(starting_capacity, - max_capacity, locked, NULL); -} - -size_t destroy_contiguous_mspace(mspace msp) { - mstate ms = (mstate)msp; - - if (ok_magic(ms)) { - struct mspace_contig_state *cs; - size_t length; - const unsigned int pagesize = PAGESIZE; - - cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1)); - assert(cs->magic == CONTIG_STATE_MAGIC); - assert(cs->m == ms); - - length = cs->top - (char *)cs; - if (munmap((char *)cs, length) != 0) - return length; - } - else { - USAGE_ERROR_ACTION(ms, ms); - } - return 0; -} -#endif diff --git a/libcutils/private.h b/libcutils/private.h deleted file mode 100644 index 2837b70c101e59df916d3bb49b44a21aa0d797f5..0000000000000000000000000000000000000000 --- a/libcutils/private.h +++ /dev/null @@ -1,368 +0,0 @@ -#ifndef PRIVATE_H - -#define PRIVATE_H - -/* -** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson. -*/ - -/* -** This header is for use ONLY with the time conversion code. -** There is no guarantee that it will remain unchanged, -** or that it will remain at all. -** Do NOT copy it to any system include directory. -** Thank you! -*/ - -/* -** ID -*/ - -#ifndef lint -#ifndef NOID -static char privatehid[] = "@(#)private.h 8.2"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -#define GRANDPARENTED "Local time zone must be set--see zic manual page" - -/* -** Defaults for preprocessor symbols. -** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. -*/ - -#ifndef HAVE_ADJTIME -#define HAVE_ADJTIME 1 -#endif /* !defined HAVE_ADJTIME */ - -#ifndef HAVE_GETTEXT -#define HAVE_GETTEXT 0 -#endif /* !defined HAVE_GETTEXT */ - -#ifndef HAVE_INCOMPATIBLE_CTIME_R -#define HAVE_INCOMPATIBLE_CTIME_R 0 -#endif /* !defined INCOMPATIBLE_CTIME_R */ - -#ifndef HAVE_SETTIMEOFDAY -#define HAVE_SETTIMEOFDAY 3 -#endif /* !defined HAVE_SETTIMEOFDAY */ - -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - -#ifndef HAVE_SYMLINK -#define HAVE_SYMLINK 1 -#endif /* !defined HAVE_SYMLINK */ - -#ifndef HAVE_SYS_STAT_H -#define HAVE_SYS_STAT_H 1 -#endif /* !defined HAVE_SYS_STAT_H */ - -#ifndef HAVE_SYS_WAIT_H -#define HAVE_SYS_WAIT_H 1 -#endif /* !defined HAVE_SYS_WAIT_H */ - -#ifndef HAVE_UNISTD_H -#define HAVE_UNISTD_H 1 -#endif /* !defined HAVE_UNISTD_H */ - -#ifndef HAVE_UTMPX_H -#define HAVE_UTMPX_H 0 -#endif /* !defined HAVE_UTMPX_H */ - -#ifndef LOCALE_HOME -#define LOCALE_HOME "/usr/lib/locale" -#endif /* !defined LOCALE_HOME */ - -#if HAVE_INCOMPATIBLE_CTIME_R -#define asctime_r _incompatible_asctime_r -#define ctime_r _incompatible_ctime_r -#endif /* HAVE_INCOMPATIBLE_CTIME_R */ - -/* -** Nested includes -*/ - -#include "sys/types.h" /* for time_t */ -#include "stdio.h" -#include "errno.h" -#include "string.h" -#include "limits.h" /* for CHAR_BIT et al. */ -#include "time.h" -#include "stdlib.h" - -#if HAVE_GETTEXT -#include "libintl.h" -#endif /* HAVE_GETTEXT */ - -#if HAVE_SYS_WAIT_H -#include <sys/wait.h> /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H */ - -#ifndef WIFEXITED -#define WIFEXITED(status) (((status) & 0xff) == 0) -#endif /* !defined WIFEXITED */ -#ifndef WEXITSTATUS -#define WEXITSTATUS(status) (((status) >> 8) & 0xff) -#endif /* !defined WEXITSTATUS */ - -#if HAVE_UNISTD_H -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H */ - -#if !HAVE_UNISTD_H -#ifndef F_OK -#define F_OK 0 -#endif /* !defined F_OK */ -#ifndef R_OK -#define R_OK 4 -#endif /* !defined R_OK */ -#endif /* !HAVE_UNISTD_H */ - -/* Unlike <ctype.h>'s isdigit, this also works if c < 0 | c > UCHAR_MAX. */ -#define is_digit(c) ((unsigned)(c) - '0' <= 9) - -/* -** Define HAVE_STDINT_H's default value here, rather than at the -** start, since __GLIBC__'s value depends on previously-included -** files. -** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) -*/ -#ifndef HAVE_STDINT_H -#define HAVE_STDINT_H \ - (199901 <= __STDC_VERSION__ || \ - 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) -#endif /* !defined HAVE_STDINT_H */ - -#if HAVE_STDINT_H -#include "stdint.h" -#endif /* !HAVE_STDINT_H */ - -#ifndef INT_FAST64_MAX -/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ -#if defined LLONG_MAX || defined __LONG_LONG_MAX__ -typedef long long int_fast64_t; -#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ -#if (LONG_MAX >> 31) < 0xffffffff -Please use a compiler that supports a 64-bit integer type (or wider); -you may need to compile with "-DHAVE_STDINT_H". -#endif /* (LONG_MAX >> 31) < 0xffffffff */ -typedef long int_fast64_t; -#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ -#endif /* !defined INT_FAST64_MAX */ - -#ifndef INT32_MAX -#define INT32_MAX 0x7fffffff -#endif /* !defined INT32_MAX */ -#ifndef INT32_MIN -#define INT32_MIN (-1 - INT32_MAX) -#endif /* !defined INT32_MIN */ - -/* -** Workarounds for compilers/systems. -*/ - -/* -** If your compiler lacks prototypes, "#define P(x) ()". -*/ - -#ifndef P -#define P(x) x -#endif /* !defined P */ - -/* -** SunOS 4.1.1 headers lack EXIT_SUCCESS. -*/ - -#ifndef EXIT_SUCCESS -#define EXIT_SUCCESS 0 -#endif /* !defined EXIT_SUCCESS */ - -/* -** SunOS 4.1.1 headers lack EXIT_FAILURE. -*/ - -#ifndef EXIT_FAILURE -#define EXIT_FAILURE 1 -#endif /* !defined EXIT_FAILURE */ - -/* -** SunOS 4.1.1 headers lack FILENAME_MAX. -*/ - -#ifndef FILENAME_MAX - -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ - -#ifdef MAXPATHLEN -#define FILENAME_MAX MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX 1024 /* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ - -#endif /* !defined FILENAME_MAX */ - -/* -** SunOS 4.1.1 libraries lack remove. -*/ - -#ifndef remove -extern int unlink P((const char * filename)); -#define remove unlink -#endif /* !defined remove */ - -/* -** Some ancient errno.h implementations don't declare errno. -** But some newer errno.h implementations define it as a macro. -** Fix the former without affecting the latter. -*/ - -#ifndef errno -extern int errno; -#endif /* !defined errno */ - -/* -** Some time.h implementations don't declare asctime_r. -** Others might define it as a macro. -** Fix the former without affecting the latter. -*/ - -#ifndef asctime_r -extern char * asctime_r(); -#endif - -/* -** Private function declarations. -*/ - -char * icalloc P((int nelem, int elsize)); -char * icatalloc P((char * old, const char * new)); -char * icpyalloc P((const char * string)); -char * imalloc P((int n)); -void * irealloc P((void * pointer, int size)); -void icfree P((char * pointer)); -void ifree P((char * pointer)); -const char * scheck P((const char * string, const char * format)); - -/* -** Finally, some convenience items. -*/ - -#ifndef TRUE -#define TRUE 1 -#endif /* !defined TRUE */ - -#ifndef FALSE -#define FALSE 0 -#endif /* !defined FALSE */ - -#ifndef TYPE_BIT -#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) -#endif /* !defined TYPE_BIT */ - -#ifndef TYPE_SIGNED -#define TYPE_SIGNED(type) (((type) -1) < 0) -#endif /* !defined TYPE_SIGNED */ - -/* -** Since the definition of TYPE_INTEGRAL contains floating point numbers, -** it cannot be used in preprocessor directives. -*/ - -#ifndef TYPE_INTEGRAL -#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) -#endif /* !defined TYPE_INTEGRAL */ - -#ifndef INT_STRLEN_MAXIMUM -/* -** 302 / 1000 is log10(2.0) rounded up. -** Subtract one for the sign bit if the type is signed; -** add one for integer division truncation; -** add one more for a minus sign if the type is signed. -*/ -#define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ - 1 + TYPE_SIGNED(type)) -#endif /* !defined INT_STRLEN_MAXIMUM */ - -/* -** INITIALIZE(x) -*/ - -#ifndef GNUC_or_lint -#ifdef lint -#define GNUC_or_lint -#endif /* defined lint */ -#ifndef lint -#ifdef __GNUC__ -#define GNUC_or_lint -#endif /* defined __GNUC__ */ -#endif /* !defined lint */ -#endif /* !defined GNUC_or_lint */ - -#ifndef INITIALIZE -#ifdef GNUC_or_lint -#define INITIALIZE(x) ((x) = 0) -#endif /* defined GNUC_or_lint */ -#ifndef GNUC_or_lint -#define INITIALIZE(x) -#endif /* !defined GNUC_or_lint */ -#endif /* !defined INITIALIZE */ - -/* -** For the benefit of GNU folk... -** `_(MSGID)' uses the current locale's message library string for MSGID. -** The default is to use gettext if available, and use MSGID otherwise. -*/ - -#ifndef _ -#if HAVE_GETTEXT -#define _(msgid) gettext(msgid) -#else /* !HAVE_GETTEXT */ -#define _(msgid) msgid -#endif /* !HAVE_GETTEXT */ -#endif /* !defined _ */ - -#ifndef TZ_DOMAIN -#define TZ_DOMAIN "tz" -#endif /* !defined TZ_DOMAIN */ - -#if HAVE_INCOMPATIBLE_CTIME_R -#undef asctime_r -#undef ctime_r -char *asctime_r P((struct tm const *, char *)); -char *ctime_r P((time_t const *, char *)); -#endif /* HAVE_INCOMPATIBLE_CTIME_R */ - -#ifndef YEARSPERREPEAT -#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ -#endif /* !defined YEARSPERREPEAT */ - -/* -** The Gregorian year averages 365.2425 days, which is 31556952 seconds. -*/ - -#ifndef AVGSECSPERYEAR -#define AVGSECSPERYEAR 31556952L -#endif /* !defined AVGSECSPERYEAR */ - -#ifndef SECSPERREPEAT -#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) -#endif /* !defined SECSPERREPEAT */ - -#ifndef SECSPERREPEAT_BITS -#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ -#endif /* !defined SECSPERREPEAT_BITS */ - -/* -** UNIX was a registered trademark of The Open Group in 2003. -*/ - -#endif /* !defined PRIVATE_H */ diff --git a/libcutils/process_name.c b/libcutils/process_name.c deleted file mode 100644 index 17f52e2698b0d2662d89652faac1d1856f5b4563..0000000000000000000000000000000000000000 --- a/libcutils/process_name.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <cutils/process_name.h> -#include <cutils/properties.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> - -#define PROCESS_NAME_DEVICE "/sys/qemu_trace/process_name" - -static const char* process_name = "unknown"; -static int running_in_emulator = -1; - -void set_process_name(const char* new_name) { - char propBuf[PROPERTY_VALUE_MAX]; - - if (new_name == NULL) { - return; - } - - // We never free the old name. Someone else could be using it. - char* copy = (char*) malloc(strlen(new_name) + 1); - strcpy(copy, new_name); - process_name = (const char*) copy; - - // If we know we are not running in the emulator, then return. - if (running_in_emulator == 0) { - return; - } - - // If the "running_in_emulator" variable has not been initialized, - // then do it now. - if (running_in_emulator == -1) { - property_get("ro.kernel.qemu", propBuf, ""); - if (propBuf[0] == '1') { - running_in_emulator = 1; - } else { - running_in_emulator = 0; - return; - } - } - - // If the emulator was started with the "-trace file" command line option - // then we want to record the process name in the trace even if we are - // not currently tracing instructions (so that we will know the process - // name when we do start tracing instructions). We do not need to execute - // this code if we are just running in the emulator without the "-trace" - // command line option, but we don't know that here and this function - // isn't called frequently enough to bother optimizing that case. - int fd = open(PROCESS_NAME_DEVICE, O_RDWR); - if (fd < 0) - return; - write(fd, process_name, strlen(process_name) + 1); - close(fd); -} - -const char* get_process_name(void) { - return process_name; -} diff --git a/libcutils/properties.c b/libcutils/properties.c deleted file mode 100644 index 547cc6dc5a847f1db06981278e0771f5753ad59e..0000000000000000000000000000000000000000 --- a/libcutils/properties.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "properties" - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <cutils/sockets.h> -#include <errno.h> -#include <assert.h> - -#include <cutils/properties.h> -#include "loghack.h" - -#ifdef HAVE_LIBC_SYSTEM_PROPERTIES - -#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ -#include <sys/_system_properties.h> - -static int send_prop_msg(prop_msg *msg) -{ - int s; - int r; - - s = socket_local_client(PROP_SERVICE_NAME, - ANDROID_SOCKET_NAMESPACE_RESERVED, - SOCK_STREAM); - if(s < 0) return -1; - - while((r = send(s, msg, sizeof(prop_msg), 0)) < 0) { - if((errno == EINTR) || (errno == EAGAIN)) continue; - break; - } - - if(r == sizeof(prop_msg)) { - r = 0; - } else { - r = -1; - } - - close(s); - return r; -} - -int property_set(const char *key, const char *value) -{ - prop_msg msg; - unsigned resp; - - if(key == 0) return -1; - if(value == 0) value = ""; - - if(strlen(key) >= PROP_NAME_MAX) return -1; - if(strlen(value) >= PROP_VALUE_MAX) return -1; - - msg.cmd = PROP_MSG_SETPROP; - strcpy((char*) msg.name, key); - strcpy((char*) msg.value, value); - - return send_prop_msg(&msg); -} - -int property_get(const char *key, char *value, const char *default_value) -{ - int len; - - len = __system_property_get(key, value); - if(len > 0) { - return len; - } - - if(default_value) { - len = strlen(default_value); - memcpy(value, default_value, len + 1); - } - return len; -} - -int property_list(void (*propfn)(const char *key, const char *value, void *cookie), - void *cookie) -{ - char name[PROP_NAME_MAX]; - char value[PROP_VALUE_MAX]; - const prop_info *pi; - unsigned n; - - for(n = 0; (pi = __system_property_find_nth(n)); n++) { - __system_property_read(pi, name, value); - propfn(name, value, cookie); - } - return 0; -} - -#elif defined(HAVE_SYSTEM_PROPERTY_SERVER) - -/* - * The Linux simulator provides a "system property server" that uses IPC - * to set/get/list properties. The file descriptor is shared by all - * threads in the process, so we use a mutex to ensure that requests - * from multiple threads don't get interleaved. - */ -#include <stdio.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <pthread.h> - -static pthread_once_t gInitOnce = PTHREAD_ONCE_INIT; -static pthread_mutex_t gPropertyFdLock = PTHREAD_MUTEX_INITIALIZER; -static int gPropFd = -1; - -/* - * Connect to the properties server. - * - * Returns the socket descriptor on success. - */ -static int connectToServer(const char* fileName) -{ - int sock = -1; - int cc; - - struct sockaddr_un addr; - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock < 0) { - LOGW("UNIX domain socket create failed (errno=%d)\n", errno); - return -1; - } - - /* connect to socket; fails if file doesn't exist */ - strcpy(addr.sun_path, fileName); // max 108 bytes - addr.sun_family = AF_UNIX; - cc = connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr)); - if (cc < 0) { - // ENOENT means socket file doesn't exist - // ECONNREFUSED means socket exists but nobody is listening - //LOGW("AF_UNIX connect failed for '%s': %s\n", - // fileName, strerror(errno)); - close(sock); - return -1; - } - - return sock; -} - -/* - * Perform one-time initialization. - */ -static void init(void) -{ - assert(gPropFd == -1); - - gPropFd = connectToServer(SYSTEM_PROPERTY_PIPE_NAME); - if (gPropFd < 0) { - //LOGW("not connected to system property server\n"); - } else { - //LOGV("Connected to system property server\n"); - } -} - -int property_get(const char *key, char *value, const char *default_value) -{ - char sendBuf[1+PROPERTY_KEY_MAX]; - char recvBuf[1+PROPERTY_VALUE_MAX]; - int len = -1; - - //LOGV("PROPERTY GET [%s]\n", key); - - pthread_once(&gInitOnce, init); - if (gPropFd < 0) { - /* this mimics the behavior of the device implementation */ - if (default_value != NULL) { - strcpy(value, default_value); - len = strlen(value); - } - return len; - } - - if (strlen(key) >= PROPERTY_KEY_MAX) return -1; - - memset(sendBuf, 0xdd, sizeof(sendBuf)); // placate valgrind - - sendBuf[0] = (char) kSystemPropertyGet; - strcpy(sendBuf+1, key); - - pthread_mutex_lock(&gPropertyFdLock); - if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) { - pthread_mutex_unlock(&gPropertyFdLock); - return -1; - } - if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) { - pthread_mutex_unlock(&gPropertyFdLock); - return -1; - } - pthread_mutex_unlock(&gPropertyFdLock); - - /* first byte is 0 if value not defined, 1 if found */ - if (recvBuf[0] == 0) { - if (default_value != NULL) { - strcpy(value, default_value); - len = strlen(value); - } else { - /* - * If the value isn't defined, hand back an empty string and - * a zero length, rather than a failure. This seems wrong, - * since you can't tell the difference between "undefined" and - * "defined but empty", but it's what the device does. - */ - value[0] = '\0'; - len = 0; - } - } else if (recvBuf[0] == 1) { - strcpy(value, recvBuf+1); - len = strlen(value); - } else { - LOGE("Got strange response to property_get request (%d)\n", - recvBuf[0]); - assert(0); - return -1; - } - //LOGV("PROP [found=%d def='%s'] (%d) [%s]: [%s]\n", - // recvBuf[0], default_value, len, key, value); - - return len; -} - - -int property_set(const char *key, const char *value) -{ - char sendBuf[1+PROPERTY_KEY_MAX+PROPERTY_VALUE_MAX]; - char recvBuf[1]; - int result = -1; - - //LOGV("PROPERTY SET [%s]: [%s]\n", key, value); - - pthread_once(&gInitOnce, init); - if (gPropFd < 0) - return -1; - - if (strlen(key) >= PROPERTY_KEY_MAX) return -1; - if (strlen(value) >= PROPERTY_VALUE_MAX) return -1; - - memset(sendBuf, 0xdd, sizeof(sendBuf)); // placate valgrind - - sendBuf[0] = (char) kSystemPropertySet; - strcpy(sendBuf+1, key); - strcpy(sendBuf+1+PROPERTY_KEY_MAX, value); - - pthread_mutex_lock(&gPropertyFdLock); - if (write(gPropFd, sendBuf, sizeof(sendBuf)) != sizeof(sendBuf)) { - pthread_mutex_unlock(&gPropertyFdLock); - return -1; - } - if (read(gPropFd, recvBuf, sizeof(recvBuf)) != sizeof(recvBuf)) { - pthread_mutex_unlock(&gPropertyFdLock); - return -1; - } - pthread_mutex_unlock(&gPropertyFdLock); - - if (recvBuf[0] != 1) - return -1; - return 0; -} - -int property_list(void (*propfn)(const char *key, const char *value, void *cookie), - void *cookie) -{ - //LOGV("PROPERTY LIST\n"); - pthread_once(&gInitOnce, init); - if (gPropFd < 0) - return -1; - - return 0; -} - -#else - -/* SUPER-cheesy place-holder implementation for Win32 */ - -#include <cutils/threads.h> - -static mutex_t env_lock = MUTEX_INITIALIZER; - -int property_get(const char *key, char *value, const char *default_value) -{ - char ename[PROPERTY_KEY_MAX + 6]; - char *p; - int len; - - len = strlen(key); - if(len >= PROPERTY_KEY_MAX) return -1; - memcpy(ename, "PROP_", 5); - memcpy(ename + 5, key, len + 1); - - mutex_lock(&env_lock); - - p = getenv(ename); - if(p == 0) p = ""; - len = strlen(p); - if(len >= PROPERTY_VALUE_MAX) { - len = PROPERTY_VALUE_MAX - 1; - } - - if((len == 0) && default_value) { - len = strlen(default_value); - memcpy(value, default_value, len + 1); - } else { - memcpy(value, p, len); - value[len] = 0; - } - - mutex_unlock(&env_lock); - - return len; -} - - -int property_set(const char *key, const char *value) -{ - char ename[PROPERTY_KEY_MAX + 6]; - char *p; - int len; - int r; - - if(strlen(value) >= PROPERTY_VALUE_MAX) return -1; - - len = strlen(key); - if(len >= PROPERTY_KEY_MAX) return -1; - memcpy(ename, "PROP_", 5); - memcpy(ename + 5, key, len + 1); - - mutex_lock(&env_lock); -#ifdef HAVE_MS_C_RUNTIME - { - char temp[256]; - snprintf( temp, sizeof(temp), "%s=%s", ename, value); - putenv(temp); - r = 0; - } -#else - r = setenv(ename, value, 1); -#endif - mutex_unlock(&env_lock); - - return r; -} - -int property_list(void (*propfn)(const char *key, const char *value, void *cookie), - void *cookie) -{ - return 0; -} - -#endif diff --git a/libcutils/record_stream.c b/libcutils/record_stream.c deleted file mode 100644 index 274423b747070c771f7bf9fcbf3773d41abb87d4..0000000000000000000000000000000000000000 --- a/libcutils/record_stream.c +++ /dev/null @@ -1,186 +0,0 @@ -/* libs/cutils/record_stream.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdlib.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <cutils/record_stream.h> -#include <string.h> -#include <stdint.h> -#ifdef HAVE_WINSOCK -#include <winsock2.h> /* for ntohl */ -#else -#include <netinet/in.h> -#endif - -#define HEADER_SIZE 4 - -struct RecordStream { - int fd; - size_t maxRecordLen; - - unsigned char *buffer; - - unsigned char *unconsumed; - unsigned char *read_end; - unsigned char *buffer_end; -}; - - -extern RecordStream *record_stream_new(int fd, size_t maxRecordLen) -{ - RecordStream *ret; - - assert (maxRecordLen <= 0xffff); - - ret = (RecordStream *)calloc(1, sizeof(RecordStream)); - - ret->fd = fd; - ret->maxRecordLen = maxRecordLen; - ret->buffer = (unsigned char *)malloc (maxRecordLen + HEADER_SIZE); - - ret->unconsumed = ret->buffer; - ret->read_end = ret->buffer; - ret->buffer_end = ret->buffer + maxRecordLen + HEADER_SIZE; - - return ret; -} - - -extern void record_stream_free(RecordStream *rs) -{ - free(rs->buffer); - free(rs); -} - - -/* returns NULL; if there isn't a full record in the buffer */ -static unsigned char * getEndOfRecord (unsigned char *p_begin, - unsigned char *p_end) -{ - size_t len; - unsigned char * p_ret; - - if (p_end < p_begin + HEADER_SIZE) { - return NULL; - } - - //First four bytes are length - len = ntohl(*((uint32_t *)p_begin)); - - p_ret = p_begin + HEADER_SIZE + len; - - if (p_end < p_ret) { - return NULL; - } - - return p_ret; -} - -static void *getNextRecord (RecordStream *p_rs, size_t *p_outRecordLen) -{ - unsigned char *record_start, *record_end; - - record_end = getEndOfRecord (p_rs->unconsumed, p_rs->read_end); - - if (record_end != NULL) { - /* one full line in the buffer */ - record_start = p_rs->unconsumed + HEADER_SIZE; - p_rs->unconsumed = record_end; - - *p_outRecordLen = record_end - record_start; - - return record_start; - } - - return NULL; -} - -/** - * Reads the next record from stream fd - * Records are prefixed by a 16-bit big endian length value - * Records may not be larger than maxRecordLen - * - * Doesn't guard against EINTR - * - * p_outRecord and p_outRecordLen may not be NULL - * - * Return 0 on success, -1 on fail - * Returns 0 with *p_outRecord set to NULL on end of stream - * Returns -1 / errno = EAGAIN if it needs to read again - */ -int record_stream_get_next (RecordStream *p_rs, void ** p_outRecord, - size_t *p_outRecordLen) -{ - void *ret; - - ssize_t countRead; - - /* is there one record already in the buffer? */ - ret = getNextRecord (p_rs, p_outRecordLen); - - if (ret != NULL) { - *p_outRecord = ret; - return 0; - } - - // if the buffer is full and we don't have a full record - if (p_rs->unconsumed == p_rs->buffer - && p_rs->read_end == p_rs->buffer_end - ) { - // this should never happen - //LOGE("max record length exceeded\n"); - assert (0); - errno = EFBIG; - return -1; - } - - if (p_rs->unconsumed != p_rs->buffer) { - // move remainder to the beginning of the buffer - size_t toMove; - - toMove = p_rs->read_end - p_rs->unconsumed; - if (toMove) { - memmove(p_rs->buffer, p_rs->unconsumed, toMove); - } - - p_rs->read_end = p_rs->buffer + toMove; - p_rs->unconsumed = p_rs->buffer; - } - - countRead = read (p_rs->fd, p_rs->read_end, p_rs->buffer_end - p_rs->read_end); - - if (countRead <= 0) { - /* note: end-of-stream drops through here too */ - *p_outRecord = NULL; - return countRead; - } - - p_rs->read_end += countRead; - - ret = getNextRecord (p_rs, p_outRecordLen); - - if (ret == NULL) { - /* not enough of a buffer to for a whole command */ - errno = EAGAIN; - return -1; - } - - *p_outRecord = ret; - return 0; -} diff --git a/libcutils/selector.c b/libcutils/selector.c deleted file mode 100644 index 9436393703e5cfc6732b409df99584aa49feb1a9..0000000000000000000000000000000000000000 --- a/libcutils/selector.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "selector" - -#include <assert.h> -#include <errno.h> -#include <pthread.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <unistd.h> - -#include <cutils/array.h> -#include <cutils/selector.h> - -#include "loghack.h" - -struct Selector { - Array* selectableFds; - bool looping; - fd_set readFds; - fd_set writeFds; - fd_set exceptFds; - int maxFd; - int wakeupPipe[2]; - SelectableFd* wakeupFd; - - bool inSelect; - pthread_mutex_t inSelectLock; -}; - -/** Reads and ignores wake up data. */ -static void eatWakeupData(SelectableFd* wakeupFd) { - static char garbage[64]; - if (read(wakeupFd->fd, garbage, sizeof(garbage)) < 0) { - if (errno == EINTR) { - LOGI("read() interrupted."); - } else { - LOG_ALWAYS_FATAL("This should never happen: %s", strerror(errno)); - } - } -} - -static void setInSelect(Selector* selector, bool inSelect) { - pthread_mutex_lock(&selector->inSelectLock); - selector->inSelect = inSelect; - pthread_mutex_unlock(&selector->inSelectLock); -} - -static bool isInSelect(Selector* selector) { - pthread_mutex_lock(&selector->inSelectLock); - bool inSelect = selector->inSelect; - pthread_mutex_unlock(&selector->inSelectLock); - return inSelect; -} - -void selectorWakeUp(Selector* selector) { - if (!isInSelect(selector)) { - // We only need to write wake-up data if we're blocked in select(). - return; - } - - static char garbage[1]; - if (write(selector->wakeupPipe[1], garbage, sizeof(garbage)) < 0) { - if (errno == EINTR) { - LOGI("read() interrupted."); - } else { - LOG_ALWAYS_FATAL("This should never happen: %s", strerror(errno)); - } - } -} - -Selector* selectorCreate(void) { - Selector* selector = calloc(1, sizeof(Selector)); - if (selector == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - selector->selectableFds = arrayCreate(); - - // Set up wake-up pipe. - if (pipe(selector->wakeupPipe) < 0) { - LOG_ALWAYS_FATAL("pipe() error: %s", strerror(errno)); - } - - LOGD("Wakeup fd: %d", selector->wakeupPipe[0]); - - SelectableFd* wakeupFd = selectorAdd(selector, selector->wakeupPipe[0]); - if (wakeupFd == NULL) { - LOG_ALWAYS_FATAL("malloc() error."); - } - wakeupFd->onReadable = &eatWakeupData; - - pthread_mutex_init(&selector->inSelectLock, NULL); - - return selector; -} - -SelectableFd* selectorAdd(Selector* selector, int fd) { - assert(selector != NULL); - - SelectableFd* selectableFd = calloc(1, sizeof(SelectableFd)); - if (selectableFd != NULL) { - selectableFd->selector = selector; - selectableFd->fd = fd; - - arrayAdd(selector->selectableFds, selectableFd); - } - - return selectableFd; -} - -/** - * Adds an fd to the given set if the callback is non-null. Returns true - * if the fd was added. - */ -static inline bool maybeAdd(SelectableFd* selectableFd, - void (*callback)(SelectableFd*), fd_set* fdSet) { - if (callback != NULL) { - FD_SET(selectableFd->fd, fdSet); - return true; - } - return false; -} - -/** - * Removes stale file descriptors and initializes file descriptor sets. - */ -static void prepareForSelect(Selector* selector) { - fd_set* exceptFds = &selector->exceptFds; - fd_set* readFds = &selector->readFds; - fd_set* writeFds = &selector->writeFds; - - FD_ZERO(exceptFds); - FD_ZERO(readFds); - FD_ZERO(writeFds); - - Array* selectableFds = selector->selectableFds; - int i = 0; - selector->maxFd = 0; - int size = arraySize(selectableFds); - while (i < size) { - SelectableFd* selectableFd = arrayGet(selectableFds, i); - if (selectableFd->remove) { - // This descriptor should be removed. - arrayRemove(selectableFds, i); - size--; - if (selectableFd->onRemove != NULL) { - selectableFd->onRemove(selectableFd); - } - free(selectableFd); - } else { - if (selectableFd->beforeSelect != NULL) { - selectableFd->beforeSelect(selectableFd); - } - - bool inSet = false; - if (maybeAdd(selectableFd, selectableFd->onExcept, exceptFds)) { - LOGD("Selecting fd %d for writing...", selectableFd->fd); - inSet = true; - } - if (maybeAdd(selectableFd, selectableFd->onReadable, readFds)) { - LOGD("Selecting fd %d for reading...", selectableFd->fd); - inSet = true; - } - if (maybeAdd(selectableFd, selectableFd->onWritable, writeFds)) { - inSet = true; - } - - if (inSet) { - // If the fd is in a set, check it against max. - int fd = selectableFd->fd; - if (fd > selector->maxFd) { - selector->maxFd = fd; - } - } - - // Move to next descriptor. - i++; - } - } -} - -/** - * Invokes a callback if the callback is non-null and the fd is in the given - * set. - */ -static inline void maybeInvoke(SelectableFd* selectableFd, - void (*callback)(SelectableFd*), fd_set* fdSet) { - if (callback != NULL && !selectableFd->remove && - FD_ISSET(selectableFd->fd, fdSet)) { - LOGD("Selected fd %d.", selectableFd->fd); - callback(selectableFd); - } -} - -/** - * Notifies user if file descriptors are readable or writable, or if - * out-of-band data is present. - */ -static void fireEvents(Selector* selector) { - Array* selectableFds = selector->selectableFds; - int size = arraySize(selectableFds); - int i; - for (i = 0; i < size; i++) { - SelectableFd* selectableFd = arrayGet(selectableFds, i); - maybeInvoke(selectableFd, selectableFd->onExcept, - &selector->exceptFds); - maybeInvoke(selectableFd, selectableFd->onReadable, - &selector->readFds); - maybeInvoke(selectableFd, selectableFd->onWritable, - &selector->writeFds); - } -} - -void selectorLoop(Selector* selector) { - // Make sure we're not already looping. - if (selector->looping) { - LOG_ALWAYS_FATAL("Already looping."); - } - selector->looping = true; - - while (true) { - setInSelect(selector, true); - - prepareForSelect(selector); - - LOGD("Entering select()."); - - // Select file descriptors. - int result = select(selector->maxFd + 1, &selector->readFds, - &selector->writeFds, &selector->exceptFds, NULL); - - LOGD("Exiting select()."); - - setInSelect(selector, false); - - if (result == -1) { - // Abort on everything except EINTR. - if (errno == EINTR) { - LOGI("select() interrupted."); - } else { - LOG_ALWAYS_FATAL("select() error: %s", - strerror(errno)); - } - } else if (result > 0) { - fireEvents(selector); - } - } -} diff --git a/libcutils/socket_inaddr_any_server.c b/libcutils/socket_inaddr_any_server.c deleted file mode 100644 index 7d5dab4c8a534702a4ecc1f542e54c7e5ec5a77f..0000000000000000000000000000000000000000 --- a/libcutils/socket_inaddr_any_server.c +++ /dev/null @@ -1,70 +0,0 @@ -/* libs/cutils/socket_inaddr_any_server.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#ifndef HAVE_WINSOCK -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#endif - -#define LISTEN_BACKLOG 4 - -/* open listen() port on any interface */ -int socket_inaddr_any_server(int port, int type) -{ - struct sockaddr_in addr; - size_t alen; - int s, n; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_ANY); - - s = socket(AF_INET, type, 0); - if(s < 0) return -1; - - n = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)); - - if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(s); - return -1; - } - - if (type == SOCK_STREAM) { - int ret; - - ret = listen(s, LISTEN_BACKLOG); - - if (ret < 0) { - close(s); - return -1; - } - } - - return s; -} diff --git a/libcutils/socket_local.h b/libcutils/socket_local.h deleted file mode 100644 index 45b9856b60408d75e99ad539756144c62ba68c9e..0000000000000000000000000000000000000000 --- a/libcutils/socket_local.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __SOCKET_LOCAL_H -#define __SOCKET_LOCAL_H - -#define FILESYSTEM_SOCKET_PREFIX "/tmp/" -#define ANDROID_RESERVED_SOCKET_PREFIX "/dev/socket/" - -/* - * Set up a given sockaddr_un, to have it refer to the given - * name in the given namespace. The namespace must be one - * of <code>ANDROID_SOCKET_NAMESPACE_ABSTRACT</code>, - * <code>ANDROID_SOCKET_NAMESPACE_RESERVED</code>, or - * <code>ANDROID_SOCKET_NAMESPACE_FILESYSTEM</code>. Upon success, - * the pointed at sockaddr_un is filled in and the pointed at - * socklen_t is set to indicate the final length. This function - * will fail if the namespace is invalid (not one of the indicated - * constants) or if the name is too long. - * - * @return 0 on success or -1 on failure - */ -int socket_make_sockaddr_un(const char *name, int namespaceId, - struct sockaddr_un *p_addr, socklen_t *alen); - -#endif diff --git a/libcutils/socket_local_client.c b/libcutils/socket_local_client.c deleted file mode 100644 index 036ce2ef13bc4fc2a37280644047ddf86bb8be2f..0000000000000000000000000000000000000000 --- a/libcutils/socket_local_client.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2006 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#ifdef HAVE_WINSOCK - -int socket_local_client(const char *name, int namespaceId, int type) -{ - errno = ENOSYS; - return -1; -} - -#else /* !HAVE_WINSOCK */ - -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/select.h> -#include <sys/types.h> - -#include "socket_local.h" - -#define LISTEN_BACKLOG 4 - -/* Documented in header file. */ -int socket_make_sockaddr_un(const char *name, int namespaceId, - struct sockaddr_un *p_addr, socklen_t *alen) -{ - memset (p_addr, 0, sizeof (*p_addr)); - size_t namelen; - - switch (namespaceId) { - case ANDROID_SOCKET_NAMESPACE_ABSTRACT: -#ifdef HAVE_LINUX_LOCAL_SOCKET_NAMESPACE - namelen = strlen(name); - - // Test with length +1 for the *initial* '\0'. - if ((namelen + 1) > sizeof(p_addr->sun_path)) { - goto error; - } - - /* - * Note: The path in this case is *not* supposed to be - * '\0'-terminated. ("man 7 unix" for the gory details.) - */ - - p_addr->sun_path[0] = 0; - memcpy(p_addr->sun_path + 1, name, namelen); -#else /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/ - /* this OS doesn't have the Linux abstract namespace */ - - namelen = strlen(name) + strlen(FILESYSTEM_SOCKET_PREFIX); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } - - strcpy(p_addr->sun_path, FILESYSTEM_SOCKET_PREFIX); - strcat(p_addr->sun_path, name); -#endif /*HAVE_LINUX_LOCAL_SOCKET_NAMESPACE*/ - break; - - case ANDROID_SOCKET_NAMESPACE_RESERVED: - namelen = strlen(name) + strlen(ANDROID_RESERVED_SOCKET_PREFIX); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } - - strcpy(p_addr->sun_path, ANDROID_RESERVED_SOCKET_PREFIX); - strcat(p_addr->sun_path, name); - break; - - case ANDROID_SOCKET_NAMESPACE_FILESYSTEM: - namelen = strlen(name); - /* unix_path_max appears to be missing on linux */ - if (namelen > sizeof(*p_addr) - - offsetof(struct sockaddr_un, sun_path) - 1) { - goto error; - } - - strcpy(p_addr->sun_path, name); - break; - default: - // invalid namespace id - return -1; - } - - p_addr->sun_family = AF_LOCAL; - *alen = namelen + offsetof(struct sockaddr_un, sun_path) + 1; - return 0; -error: - return -1; -} - -/** - * connect to peer named "name" on fd - * returns same fd or -1 on error. - * fd is not closed on error. that's your job. - * - * Used by AndroidSocketImpl - */ -int socket_local_client_connect(int fd, const char *name, int namespaceId, - int type) -{ - struct sockaddr_un addr; - socklen_t alen; - size_t namelen; - int err; - - err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); - - if (err < 0) { - goto error; - } - - if(connect(fd, (struct sockaddr *) &addr, alen) < 0) { - goto error; - } - - return fd; - -error: - return -1; -} - -/** - * connect to peer named "name" - * returns fd or -1 on error - */ -int socket_local_client(const char *name, int namespaceId, int type) -{ - int s; - - s = socket(AF_LOCAL, type, 0); - if(s < 0) return -1; - - if ( 0 > socket_local_client_connect(s, name, namespaceId, type)) { - close(s); - return -1; - } - - return s; -} - -#endif /* !HAVE_WINSOCK */ diff --git a/libcutils/socket_local_server.c b/libcutils/socket_local_server.c deleted file mode 100644 index 4971b1b1cc516c9b96ad83a45a31256c8cbc70fe..0000000000000000000000000000000000000000 --- a/libcutils/socket_local_server.c +++ /dev/null @@ -1,124 +0,0 @@ -/* libs/cutils/socket_local_server.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#ifdef HAVE_WINSOCK - -int socket_local_server(const char *name, int namespaceId, int type) -{ - errno = ENOSYS; - return -1; -} - -#else /* !HAVE_WINSOCK */ - -#include <sys/socket.h> -#include <sys/un.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include "socket_local.h" - -#define LISTEN_BACKLOG 4 - - -/** - * Binds a pre-created socket(AF_LOCAL) 's' to 'name' - * returns 's' on success, -1 on fail - * - * Does not call listen() - */ -int socket_local_server_bind(int s, const char *name, int namespaceId) -{ - struct sockaddr_un addr; - socklen_t alen; - int n; - int err; - - err = socket_make_sockaddr_un(name, namespaceId, &addr, &alen); - - if (err < 0) { - return -1; - } - - /* basically: if this is a filesystem path, unlink first */ -#ifndef HAVE_LINUX_LOCAL_SOCKET_NAMESPACE - if (1) { -#else - if (namespaceId == ANDROID_SOCKET_NAMESPACE_RESERVED - || namespaceId == ANDROID_SOCKET_NAMESPACE_FILESYSTEM) { -#endif - /*ignore ENOENT*/ - unlink(addr.sun_path); - } - - n = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)); - - if(bind(s, (struct sockaddr *) &addr, alen) < 0) { - return -1; - } - - return s; - -} - - -/** Open a server-side UNIX domain datagram socket in the Linux non-filesystem - * namespace - * - * Returns fd on success, -1 on fail - */ - -int socket_local_server(const char *name, int namespace, int type) -{ - int err; - int s; - - s = socket(AF_LOCAL, type, 0); - if (s < 0) return -1; - - err = socket_local_server_bind(s, name, namespace); - - if (err < 0) { - close(s); - return -1; - } - - if (type == SOCK_STREAM) { - int ret; - - ret = listen(s, LISTEN_BACKLOG); - - if (ret < 0) { - close(s); - return -1; - } - } - - return s; -} - -#endif /* !HAVE_WINSOCK */ diff --git a/libcutils/socket_loopback_client.c b/libcutils/socket_loopback_client.c deleted file mode 100644 index cb82c5ede3b576240915e5453e068d86a18da482..0000000000000000000000000000000000000000 --- a/libcutils/socket_loopback_client.c +++ /dev/null @@ -1,59 +0,0 @@ -/* libs/cutils/socket_loopback_client.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#ifndef HAVE_WINSOCK -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#endif - -/* Connect to port on the loopback IP interface. type is - * SOCK_STREAM or SOCK_DGRAM. - * return is a file descriptor or -1 on error - */ -int socket_loopback_client(int port, int type) -{ - struct sockaddr_in addr; - socklen_t alen; - int s; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket(AF_INET, type, 0); - if(s < 0) return -1; - - if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(s); - return -1; - } - - return s; - -} - diff --git a/libcutils/socket_loopback_server.c b/libcutils/socket_loopback_server.c deleted file mode 100644 index 3208488adde68743883aa6e81d7f86b514178811..0000000000000000000000000000000000000000 --- a/libcutils/socket_loopback_server.c +++ /dev/null @@ -1,71 +0,0 @@ -/* libs/cutils/socket_loopback_server.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#define LISTEN_BACKLOG 4 - -#ifndef HAVE_WINSOCK -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#endif - -/* open listen() port on loopback interface */ -int socket_loopback_server(int port, int type) -{ - struct sockaddr_in addr; - size_t alen; - int s, n; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - s = socket(AF_INET, type, 0); - if(s < 0) return -1; - - n = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &n, sizeof(n)); - - if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(s); - return -1; - } - - if (type == SOCK_STREAM) { - int ret; - - ret = listen(s, LISTEN_BACKLOG); - - if (ret < 0) { - close(s); - return -1; - } - } - - return s; -} - diff --git a/libcutils/socket_network_client.c b/libcutils/socket_network_client.c deleted file mode 100644 index a64006cdf4dbbe9986fa79f4f9950b3f4de8ed9f..0000000000000000000000000000000000000000 --- a/libcutils/socket_network_client.c +++ /dev/null @@ -1,65 +0,0 @@ -/* libs/cutils/socket_network_client.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/sockets.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> -#include <stddef.h> - -#ifndef HAVE_WINSOCK -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <netdb.h> -#endif - - -/* Connect to port on the IP interface. type is - * SOCK_STREAM or SOCK_DGRAM. - * return is a file descriptor or -1 on error - */ -int socket_network_client(const char *host, int port, int type) -{ - struct hostent *hp; - struct sockaddr_in addr; - socklen_t alen; - int s; - - hp = gethostbyname(host); - if(hp == 0) return -1; - - memset(&addr, 0, sizeof(addr)); - addr.sin_family = hp->h_addrtype; - addr.sin_port = htons(port); - memcpy(&addr.sin_addr, hp->h_addr, hp->h_length); - - s = socket(hp->h_addrtype, type, 0); - if(s < 0) return -1; - - if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - close(s); - return -1; - } - - return s; - -} - diff --git a/libcutils/strdup16to8.c b/libcutils/strdup16to8.c deleted file mode 100644 index fadaabed8e09b751203f3a77576b5fd2d87da71c..0000000000000000000000000000000000000000 --- a/libcutils/strdup16to8.c +++ /dev/null @@ -1,104 +0,0 @@ -/* libs/cutils/strdup16to8.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/jstring.h> -#include <assert.h> -#include <stdlib.h> - - -/** - * Given a UTF-16 string, compute the length of the corresponding UTF-8 - * string in bytes. - */ -extern size_t strnlen16to8(const char16_t* utf16Str, size_t len) -{ - size_t utf8Len = 0; - - while (len--) { - unsigned int uic = *utf16Str++; - - if (uic > 0x07ff) - utf8Len += 3; - else if (uic > 0x7f || uic == 0) - utf8Len += 2; - else - utf8Len++; - } - return utf8Len; -} - - -/** - * Convert a Java-Style UTF-16 string + length to a JNI-Style UTF-8 string. - * - * This basically means: embedded \0's in the UTF-16 string are encoded - * as "0xc0 0x80" - * - * Make sure you allocate "utf8Str" with the result of strlen16to8() + 1, - * not just "len". - * - * Please note, a terminated \0 is always added, so your result will always - * be "strlen16to8() + 1" bytes long. - */ -extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len) -{ - char* utf8cur = utf8Str; - - while (len--) { - unsigned int uic = *utf16Str++; - - if (uic > 0x07ff) { - *utf8cur++ = (uic >> 12) | 0xe0; - *utf8cur++ = ((uic >> 6) & 0x3f) | 0x80; - *utf8cur++ = (uic & 0x3f) | 0x80; - } else if (uic > 0x7f || uic == 0) { - *utf8cur++ = (uic >> 6) | 0xc0; - *utf8cur++ = (uic & 0x3f) | 0x80; - } else { - *utf8cur++ = uic; - - if (uic == 0) { - break; - } - } - } - - *utf8cur = '\0'; - - return utf8Str; -} - -/** - * Convert a UTF-16 string to UTF-8. - * - * Make sure you allocate "dest" with the result of strblen16to8(), - * not just "strlen16()". - */ -char * strndup16to8 (const char16_t* s, size_t n) -{ - char *ret; - - if (s == NULL) { - return NULL; - } - - ret = malloc(strnlen16to8(s, n) + 1); - - strncpy16to8 (ret, s, n); - - return ret; -} diff --git a/libcutils/strdup8to16.c b/libcutils/strdup8to16.c deleted file mode 100644 index 8654b0455f97dbd98afa50e590f7a6b8a4ac0fb8..0000000000000000000000000000000000000000 --- a/libcutils/strdup8to16.c +++ /dev/null @@ -1,209 +0,0 @@ -/* libs/cutils/strdup8to16.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/jstring.h> -#include <assert.h> -#include <stdlib.h> - -/* See http://www.unicode.org/reports/tr22/ for discussion - * on invalid sequences - */ - -#define UTF16_REPLACEMENT_CHAR 0xfffd - -/* Clever trick from Dianne that returns 1-4 depending on leading bit sequence*/ -#define UTF8_SEQ_LENGTH(ch) (((0xe5000000 >> ((ch >> 3) & 0x1e)) & 3) + 1) - -/* note: macro expands to multiple lines */ -#define UTF8_SHIFT_AND_MASK(unicode, byte) \ - (unicode)<<=6; (unicode) |= (0x3f & (byte)); - -#define UNICODE_UPPER_LIMIT 0x10fffd - -/** - * out_len is an out parameter (which may not be null) containing the - * length of the UTF-16 string (which may contain embedded \0's) - */ - -extern char16_t * strdup8to16 (const char* s, size_t *out_len) -{ - char16_t *ret; - size_t len; - - if (s == NULL) return NULL; - - len = strlen8to16(s); - - // no plus-one here. UTF-16 strings are not null terminated - ret = (char16_t *) malloc (sizeof(char16_t) * len); - - return strcpy8to16 (ret, s, out_len); -} - -/** - * Like "strlen", but for strings encoded with Java's modified UTF-8. - * - * The value returned is the number of UTF-16 characters required - * to represent this string. - */ -extern size_t strlen8to16 (const char* utf8Str) -{ - size_t len = 0; - int ic; - int expected = 0; - - while ((ic = *utf8Str++) != '\0') { - /* bytes that start 0? or 11 are lead bytes and count as characters.*/ - /* bytes that start 10 are extention bytes and are not counted */ - - if ((ic & 0xc0) == 0x80) { - /* count the 0x80 extention bytes. if we have more than - * expected, then start counting them because strcpy8to16 - * will insert UTF16_REPLACEMENT_CHAR's - */ - expected--; - if (expected < 0) { - len++; - } - } else { - len++; - expected = UTF8_SEQ_LENGTH(ic) - 1; - - /* this will result in a surrogate pair */ - if (expected == 3) { - len++; - } - } - } - - return len; -} - - - -/* - * Retrieve the next UTF-32 character from a UTF-8 string. - * - * Stops at inner \0's - * - * Returns UTF16_REPLACEMENT_CHAR if an invalid sequence is encountered - * - * Advances "*pUtf8Ptr" to the start of the next character. - */ -static inline uint32_t getUtf32FromUtf8(const char** pUtf8Ptr) -{ - uint32_t ret; - int seq_len; - int i; - - /* Mask for leader byte for lengths 1, 2, 3, and 4 respectively*/ - static const char leaderMask[4] = {0xff, 0x1f, 0x0f, 0x07}; - - /* Bytes that start with bits "10" are not leading characters. */ - if (((**pUtf8Ptr) & 0xc0) == 0x80) { - (*pUtf8Ptr)++; - return UTF16_REPLACEMENT_CHAR; - } - - /* note we tolerate invalid leader 11111xxx here */ - seq_len = UTF8_SEQ_LENGTH(**pUtf8Ptr); - - ret = (**pUtf8Ptr) & leaderMask [seq_len - 1]; - - if (**pUtf8Ptr == '\0') return ret; - - (*pUtf8Ptr)++; - for (i = 1; i < seq_len ; i++, (*pUtf8Ptr)++) { - if ((**pUtf8Ptr) == '\0') return UTF16_REPLACEMENT_CHAR; - if (((**pUtf8Ptr) & 0xc0) != 0x80) return UTF16_REPLACEMENT_CHAR; - - UTF8_SHIFT_AND_MASK(ret, **pUtf8Ptr); - } - - return ret; -} - - -/** - * out_len is an out parameter (which may not be null) containing the - * length of the UTF-16 string (which may contain embedded \0's) - */ - -extern char16_t * strcpy8to16 (char16_t *utf16Str, const char*utf8Str, - size_t *out_len) -{ - char16_t *dest = utf16Str; - - while (*utf8Str != '\0') { - uint32_t ret; - - ret = getUtf32FromUtf8(&utf8Str); - - if (ret <= 0xffff) { - *dest++ = (char16_t) ret; - } else if (ret <= UNICODE_UPPER_LIMIT) { - /* Create surrogate pairs */ - /* See http://en.wikipedia.org/wiki/UTF-16/UCS-2#Method_for_code_points_in_Plane_1.2C_Plane_2 */ - - *dest++ = 0xd800 | ((ret - 0x10000) >> 10); - *dest++ = 0xdc00 | ((ret - 0x10000) & 0x3ff); - } else { - *dest++ = UTF16_REPLACEMENT_CHAR; - } - } - - *out_len = dest - utf16Str; - - return utf16Str; -} - -/** - * length is the number of characters in the UTF-8 string. - * out_len is an out parameter (which may not be null) containing the - * length of the UTF-16 string (which may contain embedded \0's) - */ - -extern char16_t * strcpylen8to16 (char16_t *utf16Str, const char*utf8Str, - int length, size_t *out_len) -{ - /* TODO: Share more of this code with the method above. Only 2 lines changed. */ - - char16_t *dest = utf16Str; - - const char *end = utf8Str + length; /* This line */ - while (utf8Str < end) { /* and this line changed. */ - uint32_t ret; - - ret = getUtf32FromUtf8(&utf8Str); - - if (ret <= 0xffff) { - *dest++ = (char16_t) ret; - } else if (ret <= UNICODE_UPPER_LIMIT) { - /* Create surrogate pairs */ - /* See http://en.wikipedia.org/wiki/UTF-16/UCS-2#Method_for_code_points_in_Plane_1.2C_Plane_2 */ - - *dest++ = 0xd800 | ((ret - 0x10000) >> 10); - *dest++ = 0xdc00 | ((ret - 0x10000) & 0x3ff); - } else { - *dest++ = UTF16_REPLACEMENT_CHAR; - } - } - - *out_len = dest - utf16Str; - - return utf16Str; -} diff --git a/libcutils/threads.c b/libcutils/threads.c deleted file mode 100644 index 42cc9287187fd5d93dbce1b2a71ae1f75aae4659..0000000000000000000000000000000000000000 --- a/libcutils/threads.c +++ /dev/null @@ -1,84 +0,0 @@ -/* libs/cutils/threads.c -** -** Copyright (C) 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ -#include <cutils/threads.h> - -#ifdef HAVE_PTHREADS -void* thread_store_get( thread_store_t* store ) -{ - const pthread_key_t k = store->tls; - - if (!store->has_tls) - return NULL; - - return pthread_getspecific( store->tls ); -} - -extern void thread_store_set( thread_store_t* store, - void* value, - thread_store_destruct_t destroy) -{ - pthread_mutex_lock( &store->lock ); - if (!store->has_tls) { - if (pthread_key_create( &store->tls, destroy) != 0) { - pthread_mutex_unlock(&store->lock); - return; - } - store->has_tls = 1; - } - pthread_mutex_unlock( &store->lock ); - - pthread_setspecific( store->tls, value ); -} - -#endif - -#ifdef HAVE_WIN32_THREADS -void* thread_store_get( thread_store_t* store ) -{ - if (!store->has_tls) - return NULL; - - return (void*) TlsGetValue( store->tls ); -} - -void thread_store_set( thread_store_t* store, - void* value, - thread_store_destruct_t destroy ) -{ - /* XXX: can't use destructor on thread exit */ - if (!store->lock_init) { - store->lock_init = -1; - InitializeCriticalSection( &store->lock ); - store->lock_init = -2; - } else while (store->lock_init != -2) { - Sleep(10); /* 10ms */ - } - - EnterCriticalSection( &store->lock ); - if (!store->has_tls) { - store->tls = TlsAlloc(); - if (store->tls == TLS_OUT_OF_INDEXES) { - LeaveCriticalSection( &store->lock ); - return; - } - store->has_tls = 1; - } - LeaveCriticalSection( &store->lock ); - - TlsSetValue( store->tls, value ); -} -#endif diff --git a/libcutils/tzfile.h b/libcutils/tzfile.h deleted file mode 100644 index 8c7037558b1fd79df3f6bdac5e607752daf4c436..0000000000000000000000000000000000000000 --- a/libcutils/tzfile.h +++ /dev/null @@ -1,180 +0,0 @@ -#ifndef TZFILE_H - -#define TZFILE_H - -/* -** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson. -*/ - -/* -** This header is for use ONLY with the time conversion code. -** There is no guarantee that it will remain unchanged, -** or that it will remain at all. -** Do NOT copy it to any system include directory. -** Thank you! -*/ - -/* -** ID -*/ - -#ifndef lint -#ifndef NOID -static char tzfilehid[] = "@(#)tzfile.h 8.1"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/* -** Information about time zone files. -*/ - -#ifndef TZDIR -#define TZDIR "/usr/share/zoneinfo" /* "/android/usr/share/zoneinfo" */ /* Time zone object file directory */ -#endif /* !defined TZDIR */ - -#ifndef TZDEFAULT -#define TZDEFAULT "localtime" -#endif /* !defined TZDEFAULT */ - -#ifndef TZDEFRULES -#define TZDEFRULES "posixrules" -#endif /* !defined TZDEFRULES */ - -/* -** Each file begins with. . . -*/ - -#define TZ_MAGIC "TZif" - -struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_version[1]; /* '\0' or '2' as of 2005 */ - char tzh_reserved[15]; /* reserved--must be zero */ - char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ - char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ - char tzh_leapcnt[4]; /* coded number of leap seconds */ - char tzh_timecnt[4]; /* coded number of transition times */ - char tzh_typecnt[4]; /* coded number of local time types */ - char tzh_charcnt[4]; /* coded number of abbr. chars */ -}; - -/* -** . . .followed by. . . -** -** tzh_timecnt (char [4])s coded transition times a la time(2) -** tzh_timecnt (unsigned char)s types of local time starting at above -** tzh_typecnt repetitions of -** one (char [4]) coded UTC offset in seconds -** one (unsigned char) used to set tm_isdst -** one (unsigned char) that's an abbreviation list index -** tzh_charcnt (char)s '\0'-terminated zone abbreviations -** tzh_leapcnt repetitions of -** one (char [4]) coded leap second transition times -** one (char [4]) total correction after above -** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition -** time is standard time, if FALSE, -** transition time is wall clock time -** if absent, transition times are -** assumed to be wall clock time -** tzh_ttisgmtcnt (char)s indexed by type; if TRUE, transition -** time is UTC, if FALSE, -** transition time is local time -** if absent, transition times are -** assumed to be local time -*/ - -/* -** If tzh_version is '2' or greater, the above is followed by a second instance -** of tzhead and a second instance of the data in which each coded transition -** time uses 8 rather than 4 chars, -** then a POSIX-TZ-environment-variable-style string for use in handling -** instants after the last transition time stored in the file -** (with nothing between the newlines if there is no POSIX representation for -** such instants). -*/ - -/* -** In the current implementation, "tzset()" refuses to deal with files that -** exceed any of the limits below. -*/ - -#ifndef TZ_MAX_TIMES -#define TZ_MAX_TIMES 1200 -#endif /* !defined TZ_MAX_TIMES */ - -#ifndef TZ_MAX_TYPES -#ifndef NOSOLAR -#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ -#endif /* !defined NOSOLAR */ -#ifdef NOSOLAR -/* -** Must be at least 14 for Europe/Riga as of Jan 12 1995, -** as noted by Earl Chew. -*/ -#define TZ_MAX_TYPES 20 /* Maximum number of local time types */ -#endif /* !defined NOSOLAR */ -#endif /* !defined TZ_MAX_TYPES */ - -#ifndef TZ_MAX_CHARS -#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ - /* (limited by what unsigned chars can hold) */ -#endif /* !defined TZ_MAX_CHARS */ - -#ifndef TZ_MAX_LEAPS -#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ -#endif /* !defined TZ_MAX_LEAPS */ - -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define DAYSPERWEEK 7 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) -#define MONSPERYEAR 12 - -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -#define TM_YEAR_BASE 1900 - -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY TM_THURSDAY - -#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) - -/* -** Since everything in isleap is modulo 400 (or a factor of 400), we know that -** isleap(y) == isleap(y % 400) -** and so -** isleap(a + b) == isleap((a + b) % 400) -** or -** isleap(a + b) == isleap(a % 400 + b % 400) -** This is true even if % means modulo rather than Fortran remainder -** (which is allowed by C89 but not C99). -** We use this to avoid addition overflow problems. -*/ - -#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) - -#endif /* !defined TZFILE_H */ diff --git a/libcutils/tzstrftime.c b/libcutils/tzstrftime.c deleted file mode 100644 index 29c50154a4bfa4c14222c1fdfcd9c68ba410f9f4..0000000000000000000000000000000000000000 --- a/libcutils/tzstrftime.c +++ /dev/null @@ -1,834 +0,0 @@ -#ifndef lint -#ifndef NOID -static char elsieid[] = "@(#)strftime.c 8.1"; -/* -** Based on the UCB version with the ID appearing below. -** This is ANSIish only when "multibyte character == plain character". -*/ -#endif /* !defined NOID */ -#endif /* !defined lint */ - -#include <time.h> -#include <tzfile.h> -#include <limits.h> -#include <cutils/tztime.h> - -/* -** Copyright (c) 1989 The Regents of the University of California. -** All rights reserved. -** -** Redistribution and use in source and binary forms are permitted -** provided that the above copyright notice and this paragraph are -** duplicated in all such forms and that any documentation, -** advertising materials, and other materials related to such -** distribution and use acknowledge that the software was developed -** by the University of California, Berkeley. The name of the -** University may not be used to endorse or promote products derived -** from this software without specific prior written permission. -** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR -** IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -** WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -*/ - -#ifndef LIBC_SCCS -#ifndef lint -static const char sccsid[] = "@(#)strftime.c 5.4 (Berkeley) 3/14/89"; -#endif /* !defined lint */ -#endif /* !defined LIBC_SCCS */ - -#include <ctype.h> - -#define P(x) x - -static char * _add P((const char *, char *, const char *, int)); -static char * _conv P((int, const char *, char *, const char *)); -static char * _fmt P((const char *, const struct tm *, char *, const char *, - int *, const struct strftime_locale *Locale)); -static char * _yconv P((int, int, int, int, char *, const char *, int)); -static char * getformat P((int, char *, char *, char *, char *)); - -extern char * tzname[]; - - - - - -/* from private.h */ - -#ifndef TYPE_BIT -#define TYPE_BIT(type) (sizeof (type) * CHAR_BIT) -#endif /* !defined TYPE_BIT */ - -#ifndef TYPE_SIGNED -#define TYPE_SIGNED(type) (((type) -1) < 0) -#endif /* !defined TYPE_SIGNED */ - -#ifndef INT_STRLEN_MAXIMUM -/* - * ** 302 / 1000 is log10(2.0) rounded up. - * ** Subtract one for the sign bit if the type is signed; - * ** add one for integer division truncation; - * ** add one more for a minus sign if the type is signed. - * */ -#define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ - 1 + TYPE_SIGNED(type)) -#endif /* !defined INT_STRLEN_MAXIMUM */ - -/* end of part from private.h */ - - - - -#ifndef YEAR_2000_NAME -#define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" -#endif /* !defined YEAR_2000_NAME */ - -#define IN_NONE 0 -#define IN_SOME 1 -#define IN_THIS 2 -#define IN_ALL 3 - -#define FORCE_LOWER_CASE 0x100 - -size_t -strftime_tz(s, maxsize, format, t, Locale) -char * const s; -const size_t maxsize; -const char * const format; -const struct tm * const t; -const struct strftime_locale *Locale; -{ - char * p; - int warn; - - warn = IN_NONE; - p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn, Locale); -#if 0 - if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) { - (void) fprintf(stderr, "\n"); - if (format == NULL) - (void) fprintf(stderr, "NULL strftime format "); - else (void) fprintf(stderr, "strftime format \"%s\" ", - format); - (void) fprintf(stderr, "yields only two digits of years in "); - if (warn == IN_SOME) - (void) fprintf(stderr, "some locales"); - else if (warn == IN_THIS) - (void) fprintf(stderr, "the current locale"); - else (void) fprintf(stderr, "all locales"); - (void) fprintf(stderr, "\n"); - } -#endif /* !defined NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU */ - if (p == s + maxsize) - return 0; - *p = '\0'; - return p - s; -} - -static char *getformat(int modifier, char *normal, char *underscore, - char *dash, char *zero) { - switch (modifier) { - case '_': - return underscore; - - case '-': - return dash; - - case '0': - return zero; - } - - return normal; -} - -static char * -_fmt(format, t, pt, ptlim, warnp, Locale) -const char * format; -const struct tm * const t; -char * pt; -const char * const ptlim; -int * warnp; -const struct strftime_locale *Locale; -{ - for ( ; *format; ++format) { - if (*format == '%') { - int modifier = 0; -label: - switch (*++format) { - case '\0': - --format; - break; - case 'A': - pt = _add((t->tm_wday < 0 || - t->tm_wday >= DAYSPERWEEK) ? - "?" : Locale->weekday[t->tm_wday], - pt, ptlim, modifier); - continue; - case 'a': - pt = _add((t->tm_wday < 0 || - t->tm_wday >= DAYSPERWEEK) ? - "?" : Locale->wday[t->tm_wday], - pt, ptlim, modifier); - continue; - case 'B': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? - "?" : Locale->month[t->tm_mon], - pt, ptlim, modifier); - continue; - case 'b': - case 'h': - pt = _add((t->tm_mon < 0 || - t->tm_mon >= MONSPERYEAR) ? - "?" : Locale->mon[t->tm_mon], - pt, ptlim, modifier); - continue; - case 'C': - /* - ** %C used to do a... - ** _fmt("%a %b %e %X %Y", t); - ** ...whereas now POSIX 1003.2 calls for - ** something completely different. - ** (ado, 1993-05-24) - */ - pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, - pt, ptlim, modifier); - continue; - case 'c': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->c_fmt, t, pt, ptlim, warnp, Locale); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } - continue; - case 'D': - pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp, Locale); - continue; - case 'd': - pt = _conv(t->tm_mday, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'E': - case 'O': - /* - ** C99 locale modifiers. - ** The sequences - ** %Ec %EC %Ex %EX %Ey %EY - ** %Od %oe %OH %OI %Om %OM - ** %OS %Ou %OU %OV %Ow %OW %Oy - ** are supposed to provide alternate - ** representations. - */ - goto label; - case '_': - case '-': - case '0': - case '^': - case '#': - modifier = *format; - goto label; - case 'e': - pt = _conv(t->tm_mday, - getformat(modifier, "%2d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'F': - pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp, Locale); - continue; - case 'H': - pt = _conv(t->tm_hour, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'I': - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'j': - pt = _conv(t->tm_yday + 1, - getformat(modifier, "%03d", "%3d", "%d", "%03d"), - pt, ptlim); - continue; - case 'k': - /* - ** This used to be... - ** _conv(t->tm_hour % 12 ? - ** t->tm_hour % 12 : 12, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 1993-05-24) - */ - pt = _conv(t->tm_hour, - getformat(modifier, "%2d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; -#ifdef KITCHEN_SINK - case 'K': - /* - ** After all this time, still unclaimed! - */ - pt = _add("kitchen sink", pt, ptlim, modifier); - continue; -#endif /* defined KITCHEN_SINK */ - case 'l': - /* - ** This used to be... - ** _conv(t->tm_hour, 2, ' '); - ** ...and has been changed to the below to - ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and - ** "%l" have been swapped. - ** (ado, 1993-05-24) - */ - pt = _conv((t->tm_hour % 12) ? - (t->tm_hour % 12) : 12, - getformat(modifier, "%2d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'M': - pt = _conv(t->tm_min, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'm': - pt = _conv(t->tm_mon + 1, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'n': - pt = _add("\n", pt, ptlim, modifier); - continue; - case 'p': - pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? - Locale->pm : - Locale->am, - pt, ptlim, modifier); - continue; - case 'P': - pt = _add((t->tm_hour >= (HOURSPERDAY / 2)) ? - Locale->pm : - Locale->am, - pt, ptlim, FORCE_LOWER_CASE); - continue; - case 'R': - pt = _fmt("%H:%M", t, pt, ptlim, warnp, Locale); - continue; - case 'r': - pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp, Locale); - continue; - case 'S': - pt = _conv(t->tm_sec, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 's': - { - struct tm tm; - char buf[INT_STRLEN_MAXIMUM( - time_t) + 1]; - time_t mkt; - - tm = *t; - mkt = mktime(&tm); - if (TYPE_SIGNED(time_t)) - (void) sprintf(buf, "%ld", - (long) mkt); - else (void) sprintf(buf, "%lu", - (unsigned long) mkt); - pt = _add(buf, pt, ptlim, modifier); - } - continue; - case 'T': - pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp, Locale); - continue; - case 't': - pt = _add("\t", pt, ptlim, modifier); - continue; - case 'U': - pt = _conv((t->tm_yday + DAYSPERWEEK - - t->tm_wday) / DAYSPERWEEK, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'u': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "ISO 8601: Weekday as a decimal number - ** [1 (Monday) - 7]" - ** (ado, 1993-05-24) - */ - pt = _conv((t->tm_wday == 0) ? - DAYSPERWEEK : t->tm_wday, "%d", pt, ptlim); - continue; - case 'V': /* ISO 8601 week number */ - case 'G': /* ISO 8601 year (four digits) */ - case 'g': /* ISO 8601 year (two digits) */ -/* -** From Arnold Robbins' strftime version 3.0: "the week number of the -** year (the first Monday as the first day of week 1) as a decimal number -** (01-53)." -** (ado, 1993-05-24) -** -** From "http://www.ft.uni-erlangen.de/~mskuhn/iso-time.html" by Markus Kuhn: -** "Week 01 of a year is per definition the first week which has the -** Thursday in this year, which is equivalent to the week which contains -** the fourth day of January. In other words, the first week of a new year -** is the week which has the majority of its days in the new year. Week 01 -** might also contain days from the previous year and the week before week -** 01 of a year is the last week (52 or 53) of the previous year even if -** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7). For example, the first week of the year -** 1997 lasts from 1996-12-30 to 1997-01-05..." -** (ado, 1996-01-02) -*/ - { - int year; - int base; - int yday; - int wday; - int w; - - year = t->tm_year; - base = TM_YEAR_BASE; - yday = t->tm_yday; - wday = t->tm_wday; - for ( ; ; ) { - int len; - int bot; - int top; - - len = isleap_sum(year, base) ? - DAYSPERLYEAR : - DAYSPERNYEAR; - /* - ** What yday (-3 ... 3) does - ** the ISO year begin on? - */ - bot = ((yday + 11 - wday) % - DAYSPERWEEK) - 3; - /* - ** What yday does the NEXT - ** ISO year begin on? - */ - top = bot - - (len % DAYSPERWEEK); - if (top < -3) - top += DAYSPERWEEK; - top += len; - if (yday >= top) { - ++base; - w = 1; - break; - } - if (yday >= bot) { - w = 1 + ((yday - bot) / - DAYSPERWEEK); - break; - } - --base; - yday += isleap_sum(year, base) ? - DAYSPERLYEAR : - DAYSPERNYEAR; - } -#ifdef XPG4_1994_04_09 - if ((w == 52 && - t->tm_mon == TM_JANUARY) || - (w == 1 && - t->tm_mon == TM_DECEMBER)) - w = 53; -#endif /* defined XPG4_1994_04_09 */ - if (*format == 'V') - pt = _conv(w, - getformat(modifier, - "%02d", - "%2d", - "%d", - "%02d"), - pt, ptlim); - else if (*format == 'g') { - *warnp = IN_ALL; - pt = _yconv(year, base, 0, 1, - pt, ptlim, modifier); - } else pt = _yconv(year, base, 1, 1, - pt, ptlim, modifier); - } - continue; - case 'v': - /* - ** From Arnold Robbins' strftime version 3.0: - ** "date as dd-bbb-YYYY" - ** (ado, 1993-05-24) - */ - pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp, Locale); - continue; - case 'W': - pt = _conv((t->tm_yday + DAYSPERWEEK - - (t->tm_wday ? - (t->tm_wday - 1) : - (DAYSPERWEEK - 1))) / DAYSPERWEEK, - getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - continue; - case 'w': - pt = _conv(t->tm_wday, "%d", pt, ptlim); - continue; - case 'X': - pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp, Locale); - continue; - case 'x': - { - int warn2 = IN_SOME; - - pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2, Locale); - if (warn2 == IN_ALL) - warn2 = IN_THIS; - if (warn2 > *warnp) - *warnp = warn2; - } - continue; - case 'y': - *warnp = IN_ALL; - pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, - pt, ptlim, modifier); - continue; - case 'Y': - pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, - pt, ptlim, modifier); - continue; - case 'Z': -#ifdef TM_ZONE - if (t->TM_ZONE != NULL) - pt = _add(t->TM_ZONE, pt, ptlim, - modifier); - else -#endif /* defined TM_ZONE */ - if (t->tm_isdst >= 0) - pt = _add(tzname[t->tm_isdst != 0], - pt, ptlim, modifier); - /* - ** C99 says that %Z must be replaced by the - ** empty string if the time zone is not - ** determinable. - */ - continue; - case 'z': - { - int diff; - char const * sign; - - if (t->tm_isdst < 0) - continue; -#ifdef TM_GMTOFF - diff = t->TM_GMTOFF; -#else /* !defined TM_GMTOFF */ - /* - ** C99 says that the UTC offset must - ** be computed by looking only at - ** tm_isdst. This requirement is - ** incorrect, since it means the code - ** must rely on magic (in this case - ** altzone and timezone), and the - ** magic might not have the correct - ** offset. Doing things correctly is - ** tricky and requires disobeying C99; - ** see GNU C strftime for details. - ** For now, punt and conform to the - ** standard, even though it's incorrect. - ** - ** C99 says that %z must be replaced by the - ** empty string if the time zone is not - ** determinable, so output nothing if the - ** appropriate variables are not available. - */ - if (t->tm_isdst == 0) -#ifdef USG_COMPAT - diff = -timezone; -#else /* !defined USG_COMPAT */ - continue; -#endif /* !defined USG_COMPAT */ - else -#ifdef ALTZONE - diff = -altzone; -#else /* !defined ALTZONE */ - continue; -#endif /* !defined ALTZONE */ -#endif /* !defined TM_GMTOFF */ - if (diff < 0) { - sign = "-"; - diff = -diff; - } else sign = "+"; - pt = _add(sign, pt, ptlim, modifier); - diff /= SECSPERMIN; - diff = (diff / MINSPERHOUR) * 100 + - (diff % MINSPERHOUR); - pt = _conv(diff, - getformat(modifier, "%04d", - "%4d", "%d", "%04d"), - pt, ptlim); - } - continue; - case '+': - pt = _fmt(Locale->date_fmt, t, pt, ptlim, - warnp, Locale); - continue; - case '%': - /* - ** X311J/88-090 (4.12.3.5): if conversion char is - ** undefined, behavior is undefined. Print out the - ** character itself as printf(3) also does. - */ - default: - break; - } - } - if (pt == ptlim) - break; - *pt++ = *format; - } - return pt; -} - -static char * -_conv(n, format, pt, ptlim) -const int n; -const char * const format; -char * const pt; -const char * const ptlim; -{ - char buf[INT_STRLEN_MAXIMUM(int) + 1]; - - (void) sprintf(buf, format, n); - return _add(buf, pt, ptlim, 0); -} - -static char * -_add(str, pt, ptlim, modifier) -const char * str; -char * pt; -const char * const ptlim; -int modifier; -{ - int c; - - switch (modifier) { - case FORCE_LOWER_CASE: - while (pt < ptlim && (*pt = tolower(*str++)) != '\0') { - ++pt; - } - break; - - case '^': - while (pt < ptlim && (*pt = toupper(*str++)) != '\0') { - ++pt; - } - break; - - case '#': - while (pt < ptlim && (c = *str++) != '\0') { - if (isupper(c)) { - c = tolower(c); - } else if (islower(c)) { - c = toupper(c); - } - *pt = c; - ++pt; - } - - break; - - default: - while (pt < ptlim && (*pt = *str++) != '\0') { - ++pt; - } - } - - return pt; -} - -/* -** POSIX and the C Standard are unclear or inconsistent about -** what %C and %y do if the year is negative or exceeds 9999. -** Use the convention that %C concatenated with %y yields the -** same output as %Y, and that %Y contains at least 4 bytes, -** with more only if necessary. -*/ - -static char * -_yconv(a, b, convert_top, convert_yy, pt, ptlim, modifier) -const int a; -const int b; -const int convert_top; -const int convert_yy; -char * pt; -const char * const ptlim; -int modifier; -{ - register int lead; - register int trail; - -#define DIVISOR 100 - trail = a % DIVISOR + b % DIVISOR; - lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; - trail %= DIVISOR; - if (trail < 0 && lead > 0) { - trail += DIVISOR; - --lead; - } else if (lead < 0 && trail > 0) { - trail -= DIVISOR; - ++lead; - } - if (convert_top) { - if (lead == 0 && trail < 0) - pt = _add("-0", pt, ptlim, modifier); - else pt = _conv(lead, getformat(modifier, "%02d", - "%2d", "%d", "%02d"), - pt, ptlim); - } - if (convert_yy) - pt = _conv(((trail < 0) ? -trail : trail), - getformat(modifier, "%02d", "%2d", "%d", "%02d"), - pt, ptlim); - return pt; -} - -#ifdef LOCALE_HOME -static struct lc_time_T * -_loc P((void)) -{ - static const char locale_home[] = LOCALE_HOME; - static const char lc_time[] = "LC_TIME"; - static char * locale_buf; - - int fd; - int oldsun; /* "...ain't got nothin' to do..." */ - char * lbuf; - char * name; - char * p; - const char ** ap; - const char * plim; - char filename[FILENAME_MAX]; - struct stat st; - size_t namesize; - size_t bufsize; - - /* - ** Use localebuf.mon[0] to signal whether locale is already set up. - */ - if (localebuf.mon[0]) - return &localebuf; - name = setlocale(LC_TIME, (char *) NULL); - if (name == NULL || *name == '\0') - goto no_locale; - /* - ** If the locale name is the same as our cache, use the cache. - */ - lbuf = locale_buf; - if (lbuf != NULL && strcmp(name, lbuf) == 0) { - p = lbuf; - for (ap = (const char **) &localebuf; - ap < (const char **) (&localebuf + 1); - ++ap) - *ap = p += strlen(p) + 1; - return &localebuf; - } - /* - ** Slurp the locale file into the cache. - */ - namesize = strlen(name) + 1; - if (sizeof filename < - ((sizeof locale_home) + namesize + (sizeof lc_time))) - goto no_locale; - oldsun = 0; - (void) sprintf(filename, "%s/%s/%s", locale_home, name, lc_time); - fd = open(filename, O_RDONLY); - if (fd < 0) { - /* - ** Old Sun systems have a different naming and data convention. - */ - oldsun = 1; - (void) sprintf(filename, "%s/%s/%s", locale_home, - lc_time, name); - fd = open(filename, O_RDONLY); - if (fd < 0) - goto no_locale; - } - if (fstat(fd, &st) != 0) - goto bad_locale; - if (st.st_size <= 0) - goto bad_locale; - bufsize = namesize + st.st_size; - locale_buf = NULL; - lbuf = (lbuf == NULL) ? malloc(bufsize) : realloc(lbuf, bufsize); - if (lbuf == NULL) - goto bad_locale; - (void) strcpy(lbuf, name); - p = lbuf + namesize; - plim = p + st.st_size; - if (read(fd, p, (size_t) st.st_size) != st.st_size) - goto bad_lbuf; - if (close(fd) != 0) - goto bad_lbuf; - /* - ** Parse the locale file into localebuf. - */ - if (plim[-1] != '\n') - goto bad_lbuf; - for (ap = (const char **) &localebuf; - ap < (const char **) (&localebuf + 1); - ++ap) { - if (p == plim) - goto bad_lbuf; - *ap = p; - while (*p != '\n') - ++p; - *p++ = '\0'; - } - if (oldsun) { - /* - ** SunOS 4 used an obsolescent format; see localdtconv(3). - ** c_fmt had the ``short format for dates and times together'' - ** (SunOS 4 date, "%a %b %e %T %Z %Y" in the C locale); - ** date_fmt had the ``long format for dates'' - ** (SunOS 4 strftime %C, "%A, %B %e, %Y" in the C locale). - ** Discard the latter in favor of the former. - */ - localebuf.date_fmt = localebuf.c_fmt; - } - /* - ** Record the successful parse in the cache. - */ - locale_buf = lbuf; - - return &localebuf; - -bad_lbuf: - free(lbuf); -bad_locale: - (void) close(fd); -no_locale: - localebuf = C_time_locale; - locale_buf = NULL; - return &localebuf; -} -#endif /* defined LOCALE_HOME */ diff --git a/libcutils/tztime.c b/libcutils/tztime.c deleted file mode 100644 index 93bbb29da1a166e75a7f26718a9444f11ba1d98c..0000000000000000000000000000000000000000 --- a/libcutils/tztime.c +++ /dev/null @@ -1,1915 +0,0 @@ -/* -** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson. -*/ - -#include <stdio.h> - -#ifndef lint -#ifndef NOID -static char elsieid[] = "@(#)localtime.c 8.3"; -#endif /* !defined NOID */ -#endif /* !defined lint */ - -/* -** Leap second handling from Bradley White. -** POSIX-style TZ environment variable handling from Guy Harris. -*/ - -/*LINTLIBRARY*/ - -#include "private.h" -#include "tzfile.h" -#include "fcntl.h" -#include "float.h" /* for FLT_MAX and DBL_MAX */ - -#ifndef TZ_ABBR_MAX_LEN -#define TZ_ABBR_MAX_LEN 16 -#endif /* !defined TZ_ABBR_MAX_LEN */ - -#ifndef TZ_ABBR_CHAR_SET -#define TZ_ABBR_CHAR_SET \ - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" -#endif /* !defined TZ_ABBR_CHAR_SET */ - -#ifndef TZ_ABBR_ERR_CHAR -#define TZ_ABBR_ERR_CHAR '_' -#endif /* !defined TZ_ABBR_ERR_CHAR */ - -#define INDEXFILE "/system/usr/share/zoneinfo/zoneinfo.idx" -#define DATAFILE "/system/usr/share/zoneinfo/zoneinfo.dat" -#define NAMELEN 40 -#define INTLEN 4 -#define READLEN (NAMELEN + 3 * INTLEN) - -/* -** SunOS 4.1.1 headers lack O_BINARY. -*/ - -#ifdef O_BINARY -#define OPEN_MODE (O_RDONLY | O_BINARY) -#endif /* defined O_BINARY */ -#ifndef O_BINARY -#define OPEN_MODE O_RDONLY -#endif /* !defined O_BINARY */ - -#ifndef WILDABBR -/* -** Someone might make incorrect use of a time zone abbreviation: -** 1. They might reference tzname[0] before calling tzset (explicitly -** or implicitly). -** 2. They might reference tzname[1] before calling tzset (explicitly -** or implicitly). -** 3. They might reference tzname[1] after setting to a time zone -** in which Daylight Saving Time is never observed. -** 4. They might reference tzname[0] after setting to a time zone -** in which Standard Time is never observed. -** 5. They might reference tm.TM_ZONE after calling offtime. -** What's best to do in the above cases is open to debate; -** for now, we just set things up so that in any of the five cases -** WILDABBR is used. Another possibility: initialize tzname[0] to the -** string "tzname[0] used before set", and similarly for the other cases. -** And another: initialize tzname[0] to "ERA", with an explanation in the -** manual page of what this "time zone abbreviation" means (doing this so -** that tzname[0] has the "normal" length of three characters). -*/ -#define WILDABBR " " -#endif /* !defined WILDABBR */ - -static char wildabbr[] = WILDABBR; - -static const char gmt[] = "GMT"; - -/* -** The DST rules to use if TZ has no rules and we can't load TZDEFRULES. -** We default to US rules as of 1999-08-17. -** POSIX 1003.1 section 8.1.1 says that the default DST rules are -** implementation dependent; for historical reasons, US rules are a -** common default. -*/ -#ifndef TZDEFRULESTRING -#define TZDEFRULESTRING ",M4.1.0,M10.5.0" -#endif /* !defined TZDEFDST */ - -struct ttinfo { /* time type information */ - long tt_gmtoff; /* UTC offset in seconds */ - int tt_isdst; /* used to set tm_isdst */ - int tt_abbrind; /* abbreviation list index */ - int tt_ttisstd; /* TRUE if transition is std time */ - int tt_ttisgmt; /* TRUE if transition is UTC */ -}; - -struct lsinfo { /* leap second information */ - time_t ls_trans; /* transition time */ - long ls_corr; /* correction to apply */ -}; - -#define BIGGEST(a, b) (((a) > (b)) ? (a) : (b)) - -#ifdef TZNAME_MAX -#define MY_TZNAME_MAX TZNAME_MAX -#endif /* defined TZNAME_MAX */ -#ifndef TZNAME_MAX -#define MY_TZNAME_MAX 255 -#endif /* !defined TZNAME_MAX */ - -struct state { - int leapcnt; - int timecnt; - int typecnt; - int charcnt; - int goback; - int goahead; - time_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; - struct ttinfo ttis[TZ_MAX_TYPES]; - char chars[BIGGEST(BIGGEST(TZ_MAX_CHARS + 1, sizeof gmt), - (2 * (MY_TZNAME_MAX + 1)))]; - struct lsinfo lsis[TZ_MAX_LEAPS]; -}; - -struct rule { - int r_type; /* type of rule--see below */ - int r_day; /* day number of rule */ - int r_week; /* week number of rule */ - int r_mon; /* month number of rule */ - long r_time; /* transition time of rule */ -}; - -#define JULIAN_DAY 0 /* Jn - Julian day */ -#define DAY_OF_YEAR 1 /* n - day of year */ -#define MONTH_NTH_DAY_OF_WEEK 2 /* Mm.n.d - month, week, day of week */ - -/* -** Prototypes for static functions. -*/ - -static long detzcode P((const char * codep)); -static time_t detzcode64 P((const char * codep)); -static int differ_by_repeat P((time_t t1, time_t t0)); -static const char * getzname P((const char * strp)); -static const char * getqzname P((const char * strp, const int delim)); -static const char * getnum P((const char * strp, int * nump, int min, - int max)); -static const char * getsecs P((const char * strp, long * secsp)); -static const char * getoffset P((const char * strp, long * offsetp)); -static const char * getrule P((const char * strp, struct rule * rulep)); -static void gmtload P((struct state * sp)); -static struct tm * gmtsub P((const time_t * timep, long offset, - struct tm * tmp)); -static struct tm * localsub P((const time_t * timep, long offset, - struct tm * tmp, struct state *sp)); -static int increment_overflow P((int * number, int delta)); -static int leaps_thru_end_of P((int y)); -static int long_increment_overflow P((long * number, int delta)); -static int long_normalize_overflow P((long * tensptr, - int * unitsptr, int base)); -static int normalize_overflow P((int * tensptr, int * unitsptr, - int base)); -static void settzname P((void)); -static time_t time1 P((struct tm * tmp, - struct tm * (*funcp) P((const time_t *, - long, struct tm *, const struct state* sp)), - long offset, const struct state * sp)); -static time_t time2 P((struct tm *tmp, - struct tm * (*funcp) P((const time_t *, - long, struct tm*, const struct state* sp)), - long offset, int * okayp, const struct state * sp)); -static time_t time2sub P((struct tm *tmp, - struct tm * (*funcp) P((const time_t*, long, struct tm*,const struct state *sp)), - long offset, int * okayp, int do_norm_secs, - const struct state *sp)); -static struct tm * timesub P((const time_t * timep, long offset, - const struct state * sp, struct tm * tmp)); -static int tmcomp P((const struct tm * atmp, - const struct tm * btmp)); -static time_t transtime P((time_t janfirst, int year, - const struct rule * rulep, long offset)); -static int tzload P((const char * name, struct state * sp, - int doextend)); -static int tzload_uncached P((const char * name, struct state * sp, - int doextend)); -static int tzparse P((const char * name, struct state * sp, - int lastditch)); - -#ifdef ALL_STATE -static struct state * gmtptr; -#endif /* defined ALL_STATE */ - -#ifndef ALL_STATE -static struct state gmtmem; -#define gmtptr (&gmtmem) -#endif /* State Farm */ - -#define CACHE_COUNT 4 -static char * g_cacheNames[CACHE_COUNT] = {0,0}; -static struct state g_cacheStates[CACHE_COUNT]; -static int g_lastCache = 0; -static struct state g_utc; -unsigned char g_utcSet = 0; - - -#ifndef TZ_STRLEN_MAX -#define TZ_STRLEN_MAX 255 -#endif /* !defined TZ_STRLEN_MAX */ - -static char lcl_TZname[TZ_STRLEN_MAX + 1]; -static int lcl_is_set; -static int gmt_is_set; - -char * tzname[2] = { - wildabbr, - wildabbr -}; - -/* -** Section 4.12.3 of X3.159-1989 requires that -** Except for the strftime function, these functions [asctime, -** ctime, gmtime, localtime] return values in one of two static -** objects: a broken-down time structure and an array of char. -** Thanks to Paul Eggert for noting this. -*/ - -static struct tm tm; - -#ifdef USG_COMPAT -time_t timezone = 0; -int daylight = 0; -#endif /* defined USG_COMPAT */ - -#ifdef ALTZONE -time_t altzone = 0; -#endif /* defined ALTZONE */ - -static long -detzcode(codep) -const char * const codep; -{ - register long result; - register int i; - - result = (codep[0] & 0x80) ? ~0L : 0; - for (i = 0; i < 4; ++i) - result = (result << 8) | (codep[i] & 0xff); - return result; -} - -static time_t -detzcode64(codep) -const char * const codep; -{ - register time_t result; - register int i; - - result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; - for (i = 0; i < 8; ++i) - result = result * 256 + (codep[i] & 0xff); - return result; -} - -static int -differ_by_repeat(t1, t0) -const time_t t1; -const time_t t0; -{ - if (TYPE_INTEGRAL(time_t) && - TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) - return 0; - return t1 - t0 == SECSPERREPEAT; -} - -static int toint(unsigned char *s) { - return (s[0] << 24) | (s[1] << 16) | (s[2] << 8) | s[3]; -} - -static int -tzload(const char *name, struct state * const sp, const int doextend) -{ - if (name) { - int i, err; - if (0 == strcmp(name, "UTC")) { - if (!g_utcSet) { - tzload_uncached(name, &g_utc, 1); - g_utcSet = 1; - } - //printf("tzload: utc\n"); - *sp = g_utc; - return 0; - } - for (i=0; i<CACHE_COUNT; i++) { - if (g_cacheNames[i] && 0 == strcmp(name, g_cacheNames[i])) { - *sp = g_cacheStates[i]; - //printf("tzload: hit: %s\n", name); - return 0; - } - } - //printf("tzload: miss: %s\n", name); - g_lastCache++; - if (g_lastCache >= CACHE_COUNT) { - g_lastCache = 0; - } - i = g_lastCache; - if (g_cacheNames[i]) { - free(g_cacheNames[i]); - } - err = tzload_uncached(name, &(g_cacheStates[i]), 1); - if (err == 0) { - g_cacheNames[i] = strdup(name); - *sp = g_cacheStates[i]; - return 0; - } else { - g_cacheNames[i] = NULL; - return err; - } - } - return tzload_uncached(name, sp, doextend); -} - -static int -tzload_uncached(name, sp, doextend) -register const char * name; -register struct state * const sp; -register const int doextend; -{ - register const char * p; - register int i; - register int fid; - register int stored; - register int nread; - union { - struct tzhead tzhead; - char buf[2 * sizeof(struct tzhead) + - 2 * sizeof *sp + - 4 * TZ_MAX_TIMES]; - } u; - int toread = sizeof u.buf; - - if (name == NULL && (name = TZDEFAULT) == NULL) - return -1; - { - register int doaccess; - /* - ** Section 4.9.1 of the C standard says that - ** "FILENAME_MAX expands to an integral constant expression - ** that is the size needed for an array of char large enough - ** to hold the longest file name string that the implementation - ** guarantees can be opened." - */ - char fullname[FILENAME_MAX + 1]; - const char *origname = name; - - if (name[0] == ':') - ++name; - doaccess = name[0] == '/'; - if (!doaccess) { - if ((p = TZDIR) == NULL) - return -1; - if ((strlen(p) + strlen(name) + 1) >= sizeof fullname) - return -1; - (void) strcpy(fullname, p); - (void) strcat(fullname, "/"); - (void) strcat(fullname, name); - /* - ** Set doaccess if '.' (as in "../") shows up in name. - */ - if (strchr(name, '.') != NULL) - doaccess = TRUE; - name = fullname; - } - if (doaccess && access(name, R_OK) != 0) - return -1; - if ((fid = open(name, OPEN_MODE)) == -1) { - char buf[READLEN]; - char name[NAMELEN + 1]; - int fidix = open(INDEXFILE, OPEN_MODE); - int off = -1; - - if (fidix < 0) { - return -1; - } - - while (read(fidix, buf, sizeof(buf)) == sizeof(buf)) { - memcpy(name, buf, NAMELEN); - name[NAMELEN] = '\0'; - - if (strcmp(name, origname) == 0) { - off = toint((unsigned char *) buf + NAMELEN); - toread = toint((unsigned char *) buf + NAMELEN + INTLEN); - break; - } - } - - close(fidix); - - if (off < 0) - return -1; - - fid = open(DATAFILE, OPEN_MODE); - - if (fid < 0) { - return -1; - } - - if (lseek(fid, off, SEEK_SET) < 0) { - return -1; - } - } - } - nread = read(fid, u.buf, toread); - if (close(fid) < 0 || nread <= 0) - return -1; - for (stored = 4; stored <= 8; stored *= 2) { - int ttisstdcnt; - int ttisgmtcnt; - - ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); - ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); - sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt); - sp->timecnt = (int) detzcode(u.tzhead.tzh_timecnt); - sp->typecnt = (int) detzcode(u.tzhead.tzh_typecnt); - sp->charcnt = (int) detzcode(u.tzhead.tzh_charcnt); - p = u.tzhead.tzh_charcnt + sizeof u.tzhead.tzh_charcnt; - if (sp->leapcnt < 0 || sp->leapcnt > TZ_MAX_LEAPS || - sp->typecnt <= 0 || sp->typecnt > TZ_MAX_TYPES || - sp->timecnt < 0 || sp->timecnt > TZ_MAX_TIMES || - sp->charcnt < 0 || sp->charcnt > TZ_MAX_CHARS || - (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || - (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) - return -1; - if (nread - (p - u.buf) < - sp->timecnt * stored + /* ats */ - sp->timecnt + /* types */ - sp->typecnt * 6 + /* ttinfos */ - sp->charcnt + /* chars */ - sp->leapcnt * (stored + 4) + /* lsinfos */ - ttisstdcnt + /* ttisstds */ - ttisgmtcnt) /* ttisgmts */ - return -1; - for (i = 0; i < sp->timecnt; ++i) { - sp->ats[i] = (stored == 4) ? - detzcode(p) : detzcode64(p); - p += stored; - } - for (i = 0; i < sp->timecnt; ++i) { - sp->types[i] = (unsigned char) *p++; - if (sp->types[i] >= sp->typecnt) - return -1; - } - for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - ttisp->tt_gmtoff = detzcode(p); - p += 4; - ttisp->tt_isdst = (unsigned char) *p++; - if (ttisp->tt_isdst != 0 && ttisp->tt_isdst != 1) - return -1; - ttisp->tt_abbrind = (unsigned char) *p++; - if (ttisp->tt_abbrind < 0 || - ttisp->tt_abbrind > sp->charcnt) - return -1; - } - for (i = 0; i < sp->charcnt; ++i) - sp->chars[i] = *p++; - sp->chars[i] = '\0'; /* ensure '\0' at end */ - for (i = 0; i < sp->leapcnt; ++i) { - register struct lsinfo * lsisp; - - lsisp = &sp->lsis[i]; - lsisp->ls_trans = (stored == 4) ? - detzcode(p) : detzcode64(p); - p += stored; - lsisp->ls_corr = detzcode(p); - p += 4; - } - for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - if (ttisstdcnt == 0) - ttisp->tt_ttisstd = FALSE; - else { - ttisp->tt_ttisstd = *p++; - if (ttisp->tt_ttisstd != TRUE && - ttisp->tt_ttisstd != FALSE) - return -1; - } - } - for (i = 0; i < sp->typecnt; ++i) { - register struct ttinfo * ttisp; - - ttisp = &sp->ttis[i]; - if (ttisgmtcnt == 0) - ttisp->tt_ttisgmt = FALSE; - else { - ttisp->tt_ttisgmt = *p++; - if (ttisp->tt_ttisgmt != TRUE && - ttisp->tt_ttisgmt != FALSE) - return -1; - } - } - /* - ** Out-of-sort ats should mean we're running on a - ** signed time_t system but using a data file with - ** unsigned values (or vice versa). - */ - for (i = 0; i < sp->timecnt - 2; ++i) - if (sp->ats[i] > sp->ats[i + 1]) { - ++i; - if (TYPE_SIGNED(time_t)) { - /* - ** Ignore the end (easy). - */ - sp->timecnt = i; - } else { - /* - ** Ignore the beginning (harder). - */ - register int j; - - for (j = 0; j + i < sp->timecnt; ++j) { - sp->ats[j] = sp->ats[j + i]; - sp->types[j] = sp->types[j + i]; - } - sp->timecnt = j; - } - break; - } - /* - ** If this is an old file, we're done. - */ - if (u.tzhead.tzh_version[0] == '\0') - break; - nread -= p - u.buf; - for (i = 0; i < nread; ++i) - u.buf[i] = p[i]; - /* - ** If this is a narrow integer time_t system, we're done. - */ - if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) - break; - } - if (doextend && nread > 2 && - u.buf[0] == '\n' && u.buf[nread - 1] == '\n' && - sp->typecnt + 2 <= TZ_MAX_TYPES) { - struct state ts; - register int result; - - u.buf[nread - 1] = '\0'; - result = tzparse(&u.buf[1], &ts, FALSE); - if (result == 0 && ts.typecnt == 2 && - sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) { - for (i = 0; i < 2; ++i) - ts.ttis[i].tt_abbrind += - sp->charcnt; - for (i = 0; i < ts.charcnt; ++i) - sp->chars[sp->charcnt++] = - ts.chars[i]; - i = 0; - while (i < ts.timecnt && - ts.ats[i] <= - sp->ats[sp->timecnt - 1]) - ++i; - while (i < ts.timecnt && - sp->timecnt < TZ_MAX_TIMES) { - sp->ats[sp->timecnt] = - ts.ats[i]; - sp->types[sp->timecnt] = - sp->typecnt + - ts.types[i]; - ++sp->timecnt; - ++i; - } - sp->ttis[sp->typecnt++] = ts.ttis[0]; - sp->ttis[sp->typecnt++] = ts.ttis[1]; - } - } - i = 2 * YEARSPERREPEAT; - sp->goback = sp->goahead = sp->timecnt > i; - sp->goback &= sp->types[i] == sp->types[0] && - differ_by_repeat(sp->ats[i], sp->ats[0]); - sp->goahead &= - sp->types[sp->timecnt - 1] == sp->types[sp->timecnt - 1 - i] && - differ_by_repeat(sp->ats[sp->timecnt - 1], - sp->ats[sp->timecnt - 1 - i]); - return 0; -} - -static const int mon_lengths[2][MONSPERYEAR] = { - { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, - { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } -}; - -static const int year_lengths[2] = { - DAYSPERNYEAR, DAYSPERLYEAR -}; - -/* -** Given a pointer into a time zone string, scan until a character that is not -** a valid character in a zone name is found. Return a pointer to that -** character. -*/ - -static const char * -getzname(strp) -register const char * strp; -{ - register char c; - - while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' && - c != '+') - ++strp; - return strp; -} - -/* -** Given a pointer into an extended time zone string, scan until the ending -** delimiter of the zone name is located. Return a pointer to the delimiter. -** -** As with getzname above, the legal character set is actually quite -** restricted, with other characters producing undefined results. -** We don't do any checking here; checking is done later in common-case code. -*/ - -static const char * -getqzname(register const char *strp, const int delim) -{ - register int c; - - while ((c = *strp) != '\0' && c != delim) - ++strp; - return strp; -} - -/* -** Given a pointer into a time zone string, extract a number from that string. -** Check that the number is within a specified range; if it is not, return -** NULL. -** Otherwise, return a pointer to the first character not part of the number. -*/ - -static const char * -getnum(strp, nump, min, max) -register const char * strp; -int * const nump; -const int min; -const int max; -{ - register char c; - register int num; - - if (strp == NULL || !is_digit(c = *strp)) - return NULL; - num = 0; - do { - num = num * 10 + (c - '0'); - if (num > max) - return NULL; /* illegal value */ - c = *++strp; - } while (is_digit(c)); - if (num < min) - return NULL; /* illegal value */ - *nump = num; - return strp; -} - -/* -** Given a pointer into a time zone string, extract a number of seconds, -** in hh[:mm[:ss]] form, from the string. -** If any error occurs, return NULL. -** Otherwise, return a pointer to the first character not part of the number -** of seconds. -*/ - -static const char * -getsecs(strp, secsp) -register const char * strp; -long * const secsp; -{ - int num; - - /* - ** `HOURSPERDAY * DAYSPERWEEK - 1' allows quasi-Posix rules like - ** "M10.4.6/26", which does not conform to Posix, - ** but which specifies the equivalent of - ** ``02:00 on the first Sunday on or after 23 Oct''. - */ - strp = getnum(strp, &num, 0, HOURSPERDAY * DAYSPERWEEK - 1); - if (strp == NULL) - return NULL; - *secsp = num * (long) SECSPERHOUR; - if (*strp == ':') { - ++strp; - strp = getnum(strp, &num, 0, MINSPERHOUR - 1); - if (strp == NULL) - return NULL; - *secsp += num * SECSPERMIN; - if (*strp == ':') { - ++strp; - /* `SECSPERMIN' allows for leap seconds. */ - strp = getnum(strp, &num, 0, SECSPERMIN); - if (strp == NULL) - return NULL; - *secsp += num; - } - } - return strp; -} - -/* -** Given a pointer into a time zone string, extract an offset, in -** [+-]hh[:mm[:ss]] form, from the string. -** If any error occurs, return NULL. -** Otherwise, return a pointer to the first character not part of the time. -*/ - -static const char * -getoffset(strp, offsetp) -register const char * strp; -long * const offsetp; -{ - register int neg = 0; - - if (*strp == '-') { - neg = 1; - ++strp; - } else if (*strp == '+') - ++strp; - strp = getsecs(strp, offsetp); - if (strp == NULL) - return NULL; /* illegal time */ - if (neg) - *offsetp = -*offsetp; - return strp; -} - -/* -** Given a pointer into a time zone string, extract a rule in the form -** date[/time]. See POSIX section 8 for the format of "date" and "time". -** If a valid rule is not found, return NULL. -** Otherwise, return a pointer to the first character not part of the rule. -*/ - -static const char * -getrule(strp, rulep) -const char * strp; -register struct rule * const rulep; -{ - if (*strp == 'J') { - /* - ** Julian day. - */ - rulep->r_type = JULIAN_DAY; - ++strp; - strp = getnum(strp, &rulep->r_day, 1, DAYSPERNYEAR); - } else if (*strp == 'M') { - /* - ** Month, week, day. - */ - rulep->r_type = MONTH_NTH_DAY_OF_WEEK; - ++strp; - strp = getnum(strp, &rulep->r_mon, 1, MONSPERYEAR); - if (strp == NULL) - return NULL; - if (*strp++ != '.') - return NULL; - strp = getnum(strp, &rulep->r_week, 1, 5); - if (strp == NULL) - return NULL; - if (*strp++ != '.') - return NULL; - strp = getnum(strp, &rulep->r_day, 0, DAYSPERWEEK - 1); - } else if (is_digit(*strp)) { - /* - ** Day of year. - */ - rulep->r_type = DAY_OF_YEAR; - strp = getnum(strp, &rulep->r_day, 0, DAYSPERLYEAR - 1); - } else return NULL; /* invalid format */ - if (strp == NULL) - return NULL; - if (*strp == '/') { - /* - ** Time specified. - */ - ++strp; - strp = getsecs(strp, &rulep->r_time); - } else rulep->r_time = 2 * SECSPERHOUR; /* default = 2:00:00 */ - return strp; -} - -/* -** Given the Epoch-relative time of January 1, 00:00:00 UTC, in a year, the -** year, a rule, and the offset from UTC at the time that rule takes effect, -** calculate the Epoch-relative time that rule takes effect. -*/ - -static time_t -transtime(janfirst, year, rulep, offset) -const time_t janfirst; -const int year; -register const struct rule * const rulep; -const long offset; -{ - register int leapyear; - register time_t value; - register int i; - int d, m1, yy0, yy1, yy2, dow; - - INITIALIZE(value); - leapyear = isleap(year); - switch (rulep->r_type) { - - case JULIAN_DAY: - /* - ** Jn - Julian day, 1 == January 1, 60 == March 1 even in leap - ** years. - ** In non-leap years, or if the day number is 59 or less, just - ** add SECSPERDAY times the day number-1 to the time of - ** January 1, midnight, to get the day. - */ - value = janfirst + (rulep->r_day - 1) * SECSPERDAY; - if (leapyear && rulep->r_day >= 60) - value += SECSPERDAY; - break; - - case DAY_OF_YEAR: - /* - ** n - day of year. - ** Just add SECSPERDAY times the day number to the time of - ** January 1, midnight, to get the day. - */ - value = janfirst + rulep->r_day * SECSPERDAY; - break; - - case MONTH_NTH_DAY_OF_WEEK: - /* - ** Mm.n.d - nth "dth day" of month m. - */ - value = janfirst; - for (i = 0; i < rulep->r_mon - 1; ++i) - value += mon_lengths[leapyear][i] * SECSPERDAY; - - /* - ** Use Zeller's Congruence to get day-of-week of first day of - ** month. - */ - m1 = (rulep->r_mon + 9) % 12 + 1; - yy0 = (rulep->r_mon <= 2) ? (year - 1) : year; - yy1 = yy0 / 100; - yy2 = yy0 % 100; - dow = ((26 * m1 - 2) / 10 + - 1 + yy2 + yy2 / 4 + yy1 / 4 - 2 * yy1) % 7; - if (dow < 0) - dow += DAYSPERWEEK; - - /* - ** "dow" is the day-of-week of the first day of the month. Get - ** the day-of-month (zero-origin) of the first "dow" day of the - ** month. - */ - d = rulep->r_day - dow; - if (d < 0) - d += DAYSPERWEEK; - for (i = 1; i < rulep->r_week; ++i) { - if (d + DAYSPERWEEK >= - mon_lengths[leapyear][rulep->r_mon - 1]) - break; - d += DAYSPERWEEK; - } - - /* - ** "d" is the day-of-month (zero-origin) of the day we want. - */ - value += d * SECSPERDAY; - break; - } - - /* - ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in - ** question. To get the Epoch-relative time of the specified local - ** time on that day, add the transition time and the current offset - ** from UTC. - */ - return value + rulep->r_time + offset; -} - -/* -** Given a POSIX section 8-style TZ string, fill in the rule tables as -** appropriate. -*/ - -static int -tzparse(name, sp, lastditch) -const char * name; -register struct state * const sp; -const int lastditch; -{ - const char * stdname; - const char * dstname; - size_t stdlen; - size_t dstlen; - long stdoffset; - long dstoffset; - register time_t * atp; - register unsigned char * typep; - register char * cp; - register int load_result; - - INITIALIZE(dstname); - stdname = name; - if (lastditch) { - stdlen = strlen(name); /* length of standard zone name */ - name += stdlen; - if (stdlen >= sizeof sp->chars) - stdlen = (sizeof sp->chars) - 1; - stdoffset = 0; - } else { - if (*name == '<') { - name++; - stdname = name; - name = getqzname(name, '>'); - if (*name != '>') - return (-1); - stdlen = name - stdname; - name++; - } else { - name = getzname(name); - stdlen = name - stdname; - } - if (*name == '\0') - return -1; - name = getoffset(name, &stdoffset); - if (name == NULL) - return -1; - } - load_result = tzload(TZDEFRULES, sp, FALSE); - if (load_result != 0) - sp->leapcnt = 0; /* so, we're off a little */ - sp->timecnt = 0; - if (*name != '\0') { - if (*name == '<') { - dstname = ++name; - name = getqzname(name, '>'); - if (*name != '>') - return -1; - dstlen = name - dstname; - name++; - } else { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - } - if (*name != '\0' && *name != ',' && *name != ';') { - name = getoffset(name, &dstoffset); - if (name == NULL) - return -1; - } else dstoffset = stdoffset - SECSPERHOUR; - if (*name == '\0' && load_result != 0) - name = TZDEFRULESTRING; - if (*name == ',' || *name == ';') { - struct rule start; - struct rule end; - register int year; - register time_t janfirst; - time_t starttime; - time_t endtime; - - ++name; - if ((name = getrule(name, &start)) == NULL) - return -1; - if (*name++ != ',') - return -1; - if ((name = getrule(name, &end)) == NULL) - return -1; - if (*name != '\0') - return -1; - sp->typecnt = 2; /* standard time and DST */ - /* - ** Two transitions per year, from EPOCH_YEAR forward. - */ - sp->ttis[0].tt_gmtoff = -dstoffset; - sp->ttis[0].tt_isdst = 1; - sp->ttis[0].tt_abbrind = stdlen + 1; - sp->ttis[1].tt_gmtoff = -stdoffset; - sp->ttis[1].tt_isdst = 0; - sp->ttis[1].tt_abbrind = 0; - atp = sp->ats; - typep = sp->types; - janfirst = 0; - for (year = EPOCH_YEAR; - sp->timecnt + 2 <= TZ_MAX_TIMES; - ++year) { - time_t newfirst; - - starttime = transtime(janfirst, year, &start, - stdoffset); - endtime = transtime(janfirst, year, &end, - dstoffset); - if (starttime > endtime) { - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - } else { - *atp++ = starttime; - *typep++ = 0; /* DST begins */ - *atp++ = endtime; - *typep++ = 1; /* DST ends */ - } - sp->timecnt += 2; - newfirst = janfirst; - newfirst += year_lengths[isleap(year)] * - SECSPERDAY; - if (newfirst <= janfirst) - break; - janfirst = newfirst; - } - } else { - register long theirstdoffset; - register long theirdstoffset; - register long theiroffset; - register int isdst; - register int i; - register int j; - - if (*name != '\0') - return -1; - /* - ** Initial values of theirstdoffset and theirdstoffset. - */ - theirstdoffset = 0; - for (i = 0; i < sp->timecnt; ++i) { - j = sp->types[i]; - if (!sp->ttis[j].tt_isdst) { - theirstdoffset = - -sp->ttis[j].tt_gmtoff; - break; - } - } - theirdstoffset = 0; - for (i = 0; i < sp->timecnt; ++i) { - j = sp->types[i]; - if (sp->ttis[j].tt_isdst) { - theirdstoffset = - -sp->ttis[j].tt_gmtoff; - break; - } - } - /* - ** Initially we're assumed to be in standard time. - */ - isdst = FALSE; - theiroffset = theirstdoffset; - /* - ** Now juggle transition times and types - ** tracking offsets as you do. - */ - for (i = 0; i < sp->timecnt; ++i) { - j = sp->types[i]; - sp->types[i] = sp->ttis[j].tt_isdst; - if (sp->ttis[j].tt_ttisgmt) { - /* No adjustment to transition time */ - } else { - /* - ** If summer time is in effect, and the - ** transition time was not specified as - ** standard time, add the summer time - ** offset to the transition time; - ** otherwise, add the standard time - ** offset to the transition time. - */ - /* - ** Transitions from DST to DDST - ** will effectively disappear since - ** POSIX provides for only one DST - ** offset. - */ - if (isdst && !sp->ttis[j].tt_ttisstd) { - sp->ats[i] += dstoffset - - theirdstoffset; - } else { - sp->ats[i] += stdoffset - - theirstdoffset; - } - } - theiroffset = -sp->ttis[j].tt_gmtoff; - if (sp->ttis[j].tt_isdst) - theirdstoffset = theiroffset; - else theirstdoffset = theiroffset; - } - /* - ** Finally, fill in ttis. - ** ttisstd and ttisgmt need not be handled. - */ - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = FALSE; - sp->ttis[0].tt_abbrind = 0; - sp->ttis[1].tt_gmtoff = -dstoffset; - sp->ttis[1].tt_isdst = TRUE; - sp->ttis[1].tt_abbrind = stdlen + 1; - sp->typecnt = 2; - } - } else { - dstlen = 0; - sp->typecnt = 1; /* only standard time */ - sp->timecnt = 0; - sp->ttis[0].tt_gmtoff = -stdoffset; - sp->ttis[0].tt_isdst = 0; - sp->ttis[0].tt_abbrind = 0; - } - sp->charcnt = stdlen + 1; - if (dstlen != 0) - sp->charcnt += dstlen + 1; - if ((size_t) sp->charcnt > sizeof sp->chars) - return -1; - cp = sp->chars; - (void) strncpy(cp, stdname, stdlen); - cp += stdlen; - *cp++ = '\0'; - if (dstlen != 0) { - (void) strncpy(cp, dstname, dstlen); - *(cp + dstlen) = '\0'; - } - return 0; -} - -static void -gmtload(sp) -struct state * const sp; -{ - if (tzload(gmt, sp, TRUE) != 0) - (void) tzparse(gmt, sp, TRUE); -} - -/* -** The easy way to behave "as if no library function calls" localtime -** is to not call it--so we drop its guts into "localsub", which can be -** freely called. (And no, the PANS doesn't require the above behavior-- -** but it *is* desirable.) -** -** The unused offset argument is for the benefit of mktime variants. -*/ - -/*ARGSUSED*/ -static struct tm * -localsub(timep, offset, tmp, sp) -const time_t * const timep; -const long offset; -struct tm * const tmp; -struct state * sp; -{ - register const struct ttinfo * ttisp; - register int i; - register struct tm * result; - const time_t t = *timep; - -#ifdef ALL_STATE - if (sp == NULL) - return gmtsub(timep, offset, tmp); -#endif /* defined ALL_STATE */ - if ((sp->goback && t < sp->ats[0]) || - (sp->goahead && t > sp->ats[sp->timecnt - 1])) { - time_t newt = t; - register time_t seconds; - register time_t tcycles; - register int_fast64_t icycles; - - if (t < sp->ats[0]) - seconds = sp->ats[0] - t; - else seconds = t - sp->ats[sp->timecnt - 1]; - --seconds; - tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; - ++tcycles; - icycles = tcycles; - if (tcycles - icycles >= 1 || icycles - tcycles >= 1) - return NULL; - seconds = icycles; - seconds *= YEARSPERREPEAT; - seconds *= AVGSECSPERYEAR; - if (t < sp->ats[0]) - newt += seconds; - else newt -= seconds; - if (newt < sp->ats[0] || - newt > sp->ats[sp->timecnt - 1]) - return NULL; /* "cannot happen" */ - result = localsub(&newt, offset, tmp, sp); - if (result == tmp) { - register time_t newy; - - newy = tmp->tm_year; - if (t < sp->ats[0]) - newy -= icycles * YEARSPERREPEAT; - else newy += icycles * YEARSPERREPEAT; - tmp->tm_year = newy; - if (tmp->tm_year != newy) - return NULL; - } - return result; - } - if (sp->timecnt == 0 || t < sp->ats[0]) { - i = 0; - while (sp->ttis[i].tt_isdst) - if (++i >= sp->typecnt) { - i = 0; - break; - } - } else { - register int lo = 1; - register int hi = sp->timecnt; - - while (lo < hi) { - register int mid = (lo + hi) >> 1; - - if (t < sp->ats[mid]) - hi = mid; - else lo = mid + 1; - } - i = (int) sp->types[lo - 1]; - } - ttisp = &sp->ttis[i]; - /* - ** To get (wrong) behavior that's compatible with System V Release 2.0 - ** you'd replace the statement below with - ** t += ttisp->tt_gmtoff; - ** timesub(&t, 0L, sp, tmp); - */ - result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); - tmp->tm_isdst = ttisp->tt_isdst; -#ifdef HAVE_TM_GMTOFF - tmp->tm_gmtoff = ttisp->tt_gmtoff; -#endif - tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; -#ifdef TM_ZONE - tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; -#endif /* defined TM_ZONE */ - return result; -} - - -// ============================================================================ -#if 0 -struct tm * -localtime(timep) -const time_t * const timep; -{ - tzset(); - return localsub(timep, 0L, &tm); -} -#endif - -/* -** Re-entrant version of localtime. -*/ - -// ============================================================================ -void -localtime_tz(const time_t * const timep, struct tm * tmp, const char* tz) -{ - struct state st; - if (tzload(tz, &st, TRUE) != 0) { - // not sure what's best here, but for now, we fall back to gmt - gmtload(&st); - } - - localsub(timep, 0L, tmp, &st); -} - -/* -** gmtsub is to gmtime as localsub is to localtime. -*/ - -static struct tm * -gmtsub(timep, offset, tmp) -const time_t * const timep; -const long offset; -struct tm * const tmp; -{ - register struct tm * result; - - if (!gmt_is_set) { - gmt_is_set = TRUE; -#ifdef ALL_STATE - gmtptr = (struct state *) malloc(sizeof *gmtptr); - if (gmtptr != NULL) -#endif /* defined ALL_STATE */ - gmtload(gmtptr); - } - result = timesub(timep, offset, gmtptr, tmp); -#ifdef TM_ZONE - /* - ** Could get fancy here and deliver something such as - ** "UTC+xxxx" or "UTC-xxxx" if offset is non-zero, - ** but this is no time for a treasure hunt. - */ - if (offset != 0) - tmp->TM_ZONE = wildabbr; - else { -#ifdef ALL_STATE - if (gmtptr == NULL) - tmp->TM_ZONE = gmt; - else tmp->TM_ZONE = gmtptr->chars; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE - tmp->TM_ZONE = gmtptr->chars; -#endif /* State Farm */ - } -#endif /* defined TM_ZONE */ - return result; -} - -// ============================================================================ -#if 0 -struct tm * -gmtime(timep) -const time_t * const timep; -{ - return gmtsub(timep, 0L, &tm); -} -#endif - -/* -* Re-entrant version of gmtime. -*/ - -// ============================================================================ -#if 0 -struct tm * -gmtime_r(timep, tmp) -const time_t * const timep; -struct tm * tmp; -{ - return gmtsub(timep, 0L, tmp); -} -#endif - -#ifdef STD_INSPIRED - -// ============================================================================ -#if 0 -struct tm * -offtime(timep, offset) -const time_t * const timep; -const long offset; -{ - return gmtsub(timep, offset, &tm); -} -#endif - -#endif /* defined STD_INSPIRED */ - -/* -** Return the number of leap years through the end of the given year -** where, to make the math easy, the answer for year zero is defined as zero. -*/ - -static int -leaps_thru_end_of(y) -register const int y; -{ - return (y >= 0) ? (y / 4 - y / 100 + y / 400) : - -(leaps_thru_end_of(-(y + 1)) + 1); -} - -static struct tm * -timesub(timep, offset, sp, tmp) -const time_t * const timep; -const long offset; -register const struct state * const sp; -register struct tm * const tmp; -{ - register const struct lsinfo * lp; - register time_t tdays; - register int idays; /* unsigned would be so 2003 */ - register long rem; - int y; - register const int * ip; - register long corr; - register int hit; - register int i; - - corr = 0; - hit = 0; -#ifdef ALL_STATE - i = (sp == NULL) ? 0 : sp->leapcnt; -#endif /* defined ALL_STATE */ -#ifndef ALL_STATE - i = sp->leapcnt; -#endif /* State Farm */ - while (--i >= 0) { - lp = &sp->lsis[i]; - if (*timep >= lp->ls_trans) { - if (*timep == lp->ls_trans) { - hit = ((i == 0 && lp->ls_corr > 0) || - lp->ls_corr > sp->lsis[i - 1].ls_corr); - if (hit) - while (i > 0 && - sp->lsis[i].ls_trans == - sp->lsis[i - 1].ls_trans + 1 && - sp->lsis[i].ls_corr == - sp->lsis[i - 1].ls_corr + 1) { - ++hit; - --i; - } - } - corr = lp->ls_corr; - break; - } - } - y = EPOCH_YEAR; - tdays = *timep / SECSPERDAY; - rem = *timep - tdays * SECSPERDAY; - while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { - int newy; - register time_t tdelta; - register int idelta; - register int leapdays; - - tdelta = tdays / DAYSPERLYEAR; - idelta = tdelta; - if (tdelta - idelta >= 1 || idelta - tdelta >= 1) - return NULL; - if (idelta == 0) - idelta = (tdays < 0) ? -1 : 1; - newy = y; - if (increment_overflow(&newy, idelta)) - return NULL; - leapdays = leaps_thru_end_of(newy - 1) - - leaps_thru_end_of(y - 1); - tdays -= ((time_t) newy - y) * DAYSPERNYEAR; - tdays -= leapdays; - y = newy; - } - { - register long seconds; - - seconds = tdays * SECSPERDAY + 0.5; - tdays = seconds / SECSPERDAY; - rem += seconds - tdays * SECSPERDAY; - } - /* - ** Given the range, we can now fearlessly cast... - */ - idays = tdays; - rem += offset - corr; - while (rem < 0) { - rem += SECSPERDAY; - --idays; - } - while (rem >= SECSPERDAY) { - rem -= SECSPERDAY; - ++idays; - } - while (idays < 0) { - if (increment_overflow(&y, -1)) - return NULL; - idays += year_lengths[isleap(y)]; - } - while (idays >= year_lengths[isleap(y)]) { - idays -= year_lengths[isleap(y)]; - if (increment_overflow(&y, 1)) - return NULL; - } - tmp->tm_year = y; - if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) - return NULL; - tmp->tm_yday = idays; - /* - ** The "extra" mods below avoid overflow problems. - */ - tmp->tm_wday = EPOCH_WDAY + - ((y - EPOCH_YEAR) % DAYSPERWEEK) * - (DAYSPERNYEAR % DAYSPERWEEK) + - leaps_thru_end_of(y - 1) - - leaps_thru_end_of(EPOCH_YEAR - 1) + - idays; - tmp->tm_wday %= DAYSPERWEEK; - if (tmp->tm_wday < 0) - tmp->tm_wday += DAYSPERWEEK; - tmp->tm_hour = (int) (rem / SECSPERHOUR); - rem %= SECSPERHOUR; - tmp->tm_min = (int) (rem / SECSPERMIN); - /* - ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. - */ - tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; - ip = mon_lengths[isleap(y)]; - for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) - idays -= ip[tmp->tm_mon]; - tmp->tm_mday = (int) (idays + 1); - tmp->tm_isdst = 0; -#ifdef TM_GMTOFF - tmp->TM_GMTOFF = offset; -#endif /* defined TM_GMTOFF */ - return tmp; -} - -// ============================================================================ -#if 0 -char * -ctime(timep) -const time_t * const timep; -{ -/* -** Section 4.12.3.2 of X3.159-1989 requires that -** The ctime function converts the calendar time pointed to by timer -** to local time in the form of a string. It is equivalent to -** asctime(localtime(timer)) -*/ - return asctime(localtime(timep)); -} -#endif - -// ============================================================================ -#if 0 -char * -ctime_r(timep, buf) -const time_t * const timep; -char * buf; -{ - struct tm mytm; - - return asctime_r(localtime_r(timep, &mytm), buf); -} -#endif - -/* -** Adapted from code provided by Robert Elz, who writes: -** The "best" way to do mktime I think is based on an idea of Bob -** Kridle's (so its said...) from a long time ago. -** It does a binary search of the time_t space. Since time_t's are -** just 32 bits, its a max of 32 iterations (even at 64 bits it -** would still be very reasonable). -*/ - -#ifndef WRONG -#define WRONG (-1) -#endif /* !defined WRONG */ - -/* -** Simplified normalize logic courtesy Paul Eggert. -*/ - -static int -increment_overflow(number, delta) -int * number; -int delta; -{ - int number0; - - number0 = *number; - *number += delta; - return (*number < number0) != (delta < 0); -} - -static int -long_increment_overflow(number, delta) -long * number; -int delta; -{ - long number0; - - number0 = *number; - *number += delta; - return (*number < number0) != (delta < 0); -} - -static int -normalize_overflow(tensptr, unitsptr, base) -int * const tensptr; -int * const unitsptr; -const int base; -{ - register int tensdelta; - - tensdelta = (*unitsptr >= 0) ? - (*unitsptr / base) : - (-1 - (-1 - *unitsptr) / base); - *unitsptr -= tensdelta * base; - return increment_overflow(tensptr, tensdelta); -} - -static int -long_normalize_overflow(tensptr, unitsptr, base) -long * const tensptr; -int * const unitsptr; -const int base; -{ - register int tensdelta; - - tensdelta = (*unitsptr >= 0) ? - (*unitsptr / base) : - (-1 - (-1 - *unitsptr) / base); - *unitsptr -= tensdelta * base; - return long_increment_overflow(tensptr, tensdelta); -} - -static int -tmcomp(atmp, btmp) -register const struct tm * const atmp; -register const struct tm * const btmp; -{ - register int result; - - if ((result = (atmp->tm_year - btmp->tm_year)) == 0 && - (result = (atmp->tm_mon - btmp->tm_mon)) == 0 && - (result = (atmp->tm_mday - btmp->tm_mday)) == 0 && - (result = (atmp->tm_hour - btmp->tm_hour)) == 0 && - (result = (atmp->tm_min - btmp->tm_min)) == 0) - result = atmp->tm_sec - btmp->tm_sec; - return result; -} - -static time_t -time2sub(tmp, funcp, offset, okayp, do_norm_secs, sp) -struct tm * const tmp; -struct tm * (* const funcp) P((const time_t*, long, struct tm*,const struct state *sp)); -const long offset; -int * const okayp; -const int do_norm_secs; -const struct state * sp; -{ - register int dir; - register int i, j; - register int saved_seconds; - register long li; - register time_t lo; - register time_t hi; - long y; - time_t newt; - time_t t; - struct tm yourtm, mytm; - - *okayp = FALSE; - yourtm = *tmp; - if (do_norm_secs) { - if (normalize_overflow(&yourtm.tm_min, &yourtm.tm_sec, - SECSPERMIN)) - return WRONG; - } - if (normalize_overflow(&yourtm.tm_hour, &yourtm.tm_min, MINSPERHOUR)) - return WRONG; - if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) - return WRONG; - y = yourtm.tm_year; - if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) - return WRONG; - /* - ** Turn y into an actual year number for now. - ** It is converted back to an offset from TM_YEAR_BASE later. - */ - if (long_increment_overflow(&y, TM_YEAR_BASE)) - return WRONG; - while (yourtm.tm_mday <= 0) { - if (long_increment_overflow(&y, -1)) - return WRONG; - li = y + (1 < yourtm.tm_mon); - yourtm.tm_mday += year_lengths[isleap(li)]; - } - while (yourtm.tm_mday > DAYSPERLYEAR) { - li = y + (1 < yourtm.tm_mon); - yourtm.tm_mday -= year_lengths[isleap(li)]; - if (long_increment_overflow(&y, 1)) - return WRONG; - } - for ( ; ; ) { - i = mon_lengths[isleap(y)][yourtm.tm_mon]; - if (yourtm.tm_mday <= i) - break; - yourtm.tm_mday -= i; - if (++yourtm.tm_mon >= MONSPERYEAR) { - yourtm.tm_mon = 0; - if (long_increment_overflow(&y, 1)) - return WRONG; - } - } - if (long_increment_overflow(&y, -TM_YEAR_BASE)) - return WRONG; - yourtm.tm_year = y; - if (yourtm.tm_year != y) - return WRONG; - if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) - saved_seconds = 0; - else if (y + TM_YEAR_BASE < EPOCH_YEAR) { - /* - ** We can't set tm_sec to 0, because that might push the - ** time below the minimum representable time. - ** Set tm_sec to 59 instead. - ** This assumes that the minimum representable time is - ** not in the same minute that a leap second was deleted from, - ** which is a safer assumption than using 58 would be. - */ - if (increment_overflow(&yourtm.tm_sec, 1 - SECSPERMIN)) - return WRONG; - saved_seconds = yourtm.tm_sec; - yourtm.tm_sec = SECSPERMIN - 1; - } else { - saved_seconds = yourtm.tm_sec; - yourtm.tm_sec = 0; - } - /* - ** Do a binary search (this works whatever time_t's type is). - */ - if (!TYPE_SIGNED(time_t)) { - lo = 0; - hi = lo - 1; - } else if (!TYPE_INTEGRAL(time_t)) { - if (sizeof(time_t) > sizeof(float)) - hi = (time_t) DBL_MAX; - else hi = (time_t) FLT_MAX; - lo = -hi; - } else { - lo = 1; - for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) - lo *= 2; - hi = -(lo + 1); - } - for ( ; ; ) { - t = lo / 2 + hi / 2; - if (t < lo) - t = lo; - else if (t > hi) - t = hi; - if ((*funcp)(&t, offset, &mytm, sp) == NULL) { - /* - ** Assume that t is too extreme to be represented in - ** a struct tm; arrange things so that it is less - ** extreme on the next pass. - */ - dir = (t > 0) ? 1 : -1; - } else dir = tmcomp(&mytm, &yourtm); - if (dir != 0) { - if (t == lo) { - ++t; - if (t <= lo) - return WRONG; - ++lo; - } else if (t == hi) { - --t; - if (t >= hi) - return WRONG; - --hi; - } - if (lo > hi) - return WRONG; - if (dir > 0) - hi = t; - else lo = t; - continue; - } - if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) - break; - /* - ** Right time, wrong type. - ** Hunt for right time, right type. - ** It's okay to guess wrong since the guess - ** gets checked. - */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ -#ifdef ALL_STATE - if (sp == NULL) - return WRONG; -#endif /* defined ALL_STATE */ - for (i = sp->typecnt - 1; i >= 0; --i) { - if (sp->ttis[i].tt_isdst != yourtm.tm_isdst) - continue; - for (j = sp->typecnt - 1; j >= 0; --j) { - if (sp->ttis[j].tt_isdst == yourtm.tm_isdst) - continue; - newt = t + sp->ttis[j].tt_gmtoff - - sp->ttis[i].tt_gmtoff; - if ((*funcp)(&newt, offset, &mytm, sp) == NULL) - continue; - if (tmcomp(&mytm, &yourtm) != 0) - continue; - if (mytm.tm_isdst != yourtm.tm_isdst) - continue; - /* - ** We have a match. - */ - t = newt; - goto label; - } - } - return WRONG; - } -label: - newt = t + saved_seconds; - if ((newt < t) != (saved_seconds < 0)) - return WRONG; - t = newt; - if ((*funcp)(&t, offset, tmp, sp)) - *okayp = TRUE; - return t; -} - -static time_t -time2(tmp, funcp, offset, okayp, sp) -struct tm * const tmp; -struct tm * (* const funcp) P((const time_t*, long, struct tm*, - const struct state* sp)); -const long offset; -int * const okayp; -const struct state * sp; -{ - time_t t; - - /* - ** First try without normalization of seconds - ** (in case tm_sec contains a value associated with a leap second). - ** If that fails, try with normalization of seconds. - */ - t = time2sub(tmp, funcp, offset, okayp, FALSE, sp); - return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp); -} - -static time_t -time1(tmp, funcp, offset, sp) -struct tm * const tmp; -struct tm * (* const funcp) P((const time_t *, long, struct tm *, const struct state* sp)); -const long offset; -const struct state * sp; -{ - register time_t t; - register int samei, otheri; - register int sameind, otherind; - register int i; - register int nseen; - int seen[TZ_MAX_TYPES]; - int types[TZ_MAX_TYPES]; - int okay; - - if (tmp->tm_isdst > 1) - tmp->tm_isdst = 1; - t = time2(tmp, funcp, offset, &okay, sp); -#define PCTS 1 -#ifdef PCTS - /* - ** PCTS code courtesy Grant Sullivan. - */ - if (okay) - return t; - if (tmp->tm_isdst < 0) - tmp->tm_isdst = 0; /* reset to std and try again */ -#endif /* defined PCTS */ -#ifndef PCTS - if (okay || tmp->tm_isdst < 0) - return t; -#endif /* !defined PCTS */ - /* - ** We're supposed to assume that somebody took a time of one type - ** and did some math on it that yielded a "struct tm" that's bad. - ** We try to divine the type they started from and adjust to the - ** type they need. - */ - /* - ** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's. - */ -#ifdef ALL_STATE - if (sp == NULL) - return WRONG; -#endif /* defined ALL_STATE */ - for (i = 0; i < sp->typecnt; ++i) - seen[i] = FALSE; - nseen = 0; - for (i = sp->timecnt - 1; i >= 0; --i) - if (!seen[sp->types[i]]) { - seen[sp->types[i]] = TRUE; - types[nseen++] = sp->types[i]; - } - for (sameind = 0; sameind < nseen; ++sameind) { - samei = types[sameind]; - if (sp->ttis[samei].tt_isdst != tmp->tm_isdst) - continue; - for (otherind = 0; otherind < nseen; ++otherind) { - otheri = types[otherind]; - if (sp->ttis[otheri].tt_isdst == tmp->tm_isdst) - continue; - tmp->tm_sec += sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; - tmp->tm_isdst = !tmp->tm_isdst; - t = time2(tmp, funcp, offset, &okay, sp); - if (okay) - return t; - tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff - - sp->ttis[samei].tt_gmtoff; - tmp->tm_isdst = !tmp->tm_isdst; - } - } - return WRONG; -} - -// ============================================================================ -time_t -mktime_tz(struct tm * const tmp, char const * tz) -{ - struct state st; - if (tzload(tz, &st, TRUE) != 0) { - // not sure what's best here, but for now, we fall back to gmt - gmtload(&st); - } - return time1(tmp, localsub, 0L, &st); -} diff --git a/libcutils/uio.c b/libcutils/uio.c deleted file mode 100644 index baa8051bcb8497e055c757b2b32b091f4bf0dbde..0000000000000000000000000000000000000000 --- a/libcutils/uio.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef HAVE_SYS_UIO_H - -#include <cutils/uio.h> -#include <unistd.h> - -int readv( int fd, struct iovec* vecs, int count ) -{ - int total = 0; - - for ( ; count > 0; count--, vecs++ ) { - const char* buf = vecs->iov_base; - int len = vecs->iov_len; - - while (len > 0) { - int ret = read( fd, buf, len ); - if (ret < 0) { - if (total == 0) - total = -1; - goto Exit; - } - if (ret == 0) - goto Exit; - - total += ret; - buf += ret; - len -= ret; - } - } -Exit: - return total; -} - -int writev( int fd, const struct iovec* vecs, int count ) -{ - int total = 0; - - for ( ; count > 0; count--, vecs++ ) { - const char* buf = (const char*)vecs->iov_base; - int len = (int)vecs->iov_len; - - while (len > 0) { - int ret = write( fd, buf, len ); - if (ret < 0) { - if (total == 0) - total = -1; - goto Exit; - } - if (ret == 0) - goto Exit; - - total += ret; - buf += ret; - len -= ret; - } - } -Exit: - return total; -} - -#endif /* !HAVE_SYS_UIO_H */ diff --git a/libcutils/zygote.c b/libcutils/zygote.c deleted file mode 100644 index aa060c05aa6bc59d9054a229a953b70387fc5ed5..0000000000000000000000000000000000000000 --- a/libcutils/zygote.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "Zygote" - -#include <cutils/sockets.h> -#include <cutils/zygote.h> -#include <cutils/log.h> - -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <stdint.h> -#include <stdlib.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <sys/types.h> -#include <sys/socket.h> - -#define ZYGOTE_SOCKET "zygote" - -#define ZYGOTE_RETRY_COUNT 1000 -#define ZYGOTE_RETRY_MILLIS 500 - -static void replace_nl(char *str); - -/* - * If sendStdio is non-zero, the current process's stdio file descriptors - * will be sent and inherited by the spawned process. - */ -static int send_request(int fd, int sendStdio, int argc, const char **argv) -{ -#ifndef HAVE_ANDROID_OS - // not supported on simulator targets - //LOGE("zygote_* not supported on simulator targets"); - return -1; -#else /* HAVE_ANDROID_OS */ - uint32_t pid; - int i; - struct iovec ivs[2]; - struct msghdr msg; - char argc_buffer[12]; - const char *newline_string = "\n"; - struct cmsghdr *cmsg; - char msgbuf[CMSG_SPACE(sizeof(int) * 3)]; - int *cmsg_payload; - ssize_t ret; - - memset(&msg, 0, sizeof(msg)); - memset(&ivs, 0, sizeof(ivs)); - - // First line is arg count - snprintf(argc_buffer, sizeof(argc_buffer), "%d\n", argc); - - ivs[0].iov_base = argc_buffer; - ivs[0].iov_len = strlen(argc_buffer); - - msg.msg_iov = ivs; - msg.msg_iovlen = 1; - - if (sendStdio != 0) { - // Pass the file descriptors with the first write - msg.msg_control = msgbuf; - msg.msg_controllen = sizeof msgbuf; - - cmsg = CMSG_FIRSTHDR(&msg); - - cmsg->cmsg_len = CMSG_LEN(3 * sizeof(int)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_RIGHTS; - - cmsg_payload = (int *)CMSG_DATA(cmsg); - cmsg_payload[0] = STDIN_FILENO; - cmsg_payload[1] = STDOUT_FILENO; - cmsg_payload[2] = STDERR_FILENO; - } - - do { - ret = sendmsg(fd, &msg, MSG_NOSIGNAL); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - return -1; - } - - // Only send the fd's once - msg.msg_control = NULL; - msg.msg_controllen = 0; - - // replace any newlines with spaces and send the args - for (i = 0; i < argc; i++) { - char *tofree = NULL; - const char *toprint; - - toprint = argv[i]; - - if (strchr(toprint, '\n') != NULL) { - tofree = strdup(toprint); - toprint = tofree; - replace_nl(tofree); - } - - ivs[0].iov_base = (char *)toprint; - ivs[0].iov_len = strlen(toprint); - ivs[1].iov_base = (char *)newline_string; - ivs[1].iov_len = 1; - - msg.msg_iovlen = 2; - - do { - ret = sendmsg(fd, &msg, MSG_NOSIGNAL); - } while (ret < 0 && errno == EINTR); - - if (tofree != NULL) { - free(tofree); - } - - if (ret < 0) { - return -1; - } - } - - // Read the pid, as a 4-byte network-order integer - - ivs[0].iov_base = &pid; - ivs[0].iov_len = sizeof(pid); - msg.msg_iovlen = 1; - - do { - do { - ret = recvmsg(fd, &msg, MSG_NOSIGNAL | MSG_WAITALL); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - return -1; - } - - ivs[0].iov_len -= ret; - ivs[0].iov_base += ret; - } while (ivs[0].iov_len > 0); - - pid = ntohl(pid); - - return pid; -#endif /* HAVE_ANDROID_OS */ -} - -int zygote_run_wait(int argc, const char **argv, void (*post_run_func)(int)) -{ - int fd; - int pid; - int err; - const char *newargv[argc + 1]; - - fd = socket_local_client(ZYGOTE_SOCKET, - ANDROID_SOCKET_NAMESPACE_RESERVED, AF_LOCAL); - - if (fd < 0) { - return -1; - } - - // The command socket is passed to the peer as close-on-exec - // and will close when the peer dies - newargv[0] = "--peer-wait"; - memcpy(newargv + 1, argv, argc * sizeof(*argv)); - - pid = send_request(fd, 1, argc + 1, newargv); - - if (pid > 0 && post_run_func != NULL) { - post_run_func(pid); - } - - // Wait for socket to close - do { - int dummy; - err = read(fd, &dummy, sizeof(dummy)); - } while ((err < 0 && errno == EINTR) || err != 0); - - do { - err = close(fd); - } while (err < 0 && errno == EINTR); - - return 0; -} - -/** - * Spawns a new dalvik instance via the Zygote process. The non-zygote - * arguments are passed to com.android.internal.os.RuntimeInit(). The - * first non-option argument should be a class name in the system class path. - * - * The arg list may start with zygote params such as --set-uid. - * - * If sendStdio is non-zero, the current process's stdio file descriptors - * will be sent and inherited by the spawned process. - * - * The pid of the child process is returned, or -1 if an error was - * encountered. - * - * zygote_run_oneshot waits up to ZYGOTE_RETRY_COUNT * - * ZYGOTE_RETRY_MILLIS for the zygote socket to be available. - */ -int zygote_run_oneshot(int sendStdio, int argc, const char **argv) -{ - int fd = -1; - int err; - int i; - int retries; - int pid; - const char **newargv = argv; - const int newargc = argc; - - for (retries = 0; (fd < 0) && (retries < ZYGOTE_RETRY_COUNT); retries++) { - if (retries > 0) { - struct timespec ts; - - memset(&ts, 0, sizeof(ts)); - ts.tv_nsec = ZYGOTE_RETRY_MILLIS * 1000 * 1000; - - do { - err = nanosleep (&ts, &ts); - } while (err < 0 && errno == EINTR); - } - fd = socket_local_client(ZYGOTE_SOCKET, AF_LOCAL, - ANDROID_SOCKET_NAMESPACE_RESERVED); - } - - if (fd < 0) { - return -1; - } - - pid = send_request(fd, 0, newargc, newargv); - - do { - err = close(fd); - } while (err < 0 && errno == EINTR); - - return pid; -} - -/** - * Replaces all occurrances of newline with space. - */ -static void replace_nl(char *str) -{ - for(; *str; str++) { - if (*str == '\n') { - *str = ' '; - } - } -} - - - diff --git a/liblog/Android.mk b/liblog/Android.mk deleted file mode 100644 index 0eec87f043b154c2dd81372e75086ac32d1f2a9f..0000000000000000000000000000000000000000 --- a/liblog/Android.mk +++ /dev/null @@ -1,72 +0,0 @@ -# -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -LOCAL_PATH := $(my-dir) -include $(CLEAR_VARS) - -liblog_sources := logd_write.c - -# some files must not be compiled when building against Mingw -# they correspond to features not used by our host development tools -# which are also hard or even impossible to port to native Win32 -WITH_MINGW := -ifeq ($(HOST_OS),windows) - ifeq ($(strip $(USE_CYGWIN)),) - WITH_MINGW := true - endif -endif -# USE_MINGW is defined when we build against Mingw on Linux -ifneq ($(strip $(USE_MINGW)),) - WITH_MINGW := true -endif - -ifndef WITH_MINGW - liblog_sources += \ - logprint.c \ - event_tag_map.c -endif - -liblog_host_sources := $(liblog_sources) fake_log_device.c - -# Static library for host -# ======================================================== -LOCAL_MODULE := liblog -LOCAL_SRC_FILES := $(liblog_host_sources) -LOCAL_LDLIBS := -lpthread -LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 -include $(BUILD_HOST_STATIC_LIBRARY) - -ifeq ($(TARGET_SIMULATOR),true) - # Shared library for simulator - # ======================================================== - include $(CLEAR_VARS) - LOCAL_MODULE := liblog - LOCAL_SRC_FILES := $(liblog_host_sources) - LOCAL_LDLIBS := -lpthread - LOCAL_CFLAGS := -DFAKE_LOG_DEVICE=1 - include $(BUILD_SHARED_LIBRARY) -else # !sim - # Shared and static library for target - # ======================================================== - include $(CLEAR_VARS) - LOCAL_MODULE := liblog - LOCAL_SRC_FILES := $(liblog_sources) - include $(BUILD_STATIC_LIBRARY) - - include $(CLEAR_VARS) - LOCAL_MODULE := liblog - LOCAL_WHOLE_STATIC_LIBRARIES := liblog - include $(BUILD_SHARED_LIBRARY) -endif # !sim diff --git a/liblog/event_tag_map.c b/liblog/event_tag_map.c deleted file mode 100644 index e70754e17ce05e5d5da5a457a1a1f683e5de436b..0000000000000000000000000000000000000000 --- a/liblog/event_tag_map.c +++ /dev/null @@ -1,438 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include "cutils/event_tag_map.h" -#include "cutils/log.h" - -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <sys/mman.h> -#include <errno.h> -#include <assert.h> - -#define OUT_TAG "EventTagMap" - -/* - * Single entry. - */ -typedef struct EventTag { - unsigned int tagIndex; - const char* tagStr; -} EventTag; - -/* - * Map. - */ -struct EventTagMap { - /* memory-mapped source file; we get strings from here */ - void* mapAddr; - size_t mapLen; - - /* array of event tags, sorted numerically by tag index */ - EventTag* tagArray; - int numTags; -}; - -/* fwd */ -static int processFile(EventTagMap* map); -static int countMapLines(const EventTagMap* map); -static int parseMapLines(EventTagMap* map); -static int scanTagLine(char** pData, EventTag* tag, int lineNum); -static int sortTags(EventTagMap* map); -static void dumpTags(const EventTagMap* map); - - -/* - * Open the map file and allocate a structure to manage it. - * - * We create a private mapping because we want to terminate the log tag - * strings with '\0'. - */ -EventTagMap* android_openEventTagMap(const char* fileName) -{ - EventTagMap* newTagMap; - off_t end; - int fd = -1; - - newTagMap = calloc(1, sizeof(EventTagMap)); - if (newTagMap == NULL) - return NULL; - - fd = open(fileName, O_RDONLY); - if (fd < 0) { - fprintf(stderr, "%s: unable to open map '%s': %s\n", - OUT_TAG, fileName, strerror(errno)); - goto fail; - } - - end = lseek(fd, 0L, SEEK_END); - (void) lseek(fd, 0L, SEEK_SET); - if (end < 0) { - fprintf(stderr, "%s: unable to seek map '%s'\n", OUT_TAG, fileName); - goto fail; - } - - newTagMap->mapAddr = mmap(NULL, end, PROT_READ | PROT_WRITE, MAP_PRIVATE, - fd, 0); - if (newTagMap->mapAddr == MAP_FAILED) { - fprintf(stderr, "%s: mmap(%s) failed: %s\n", - OUT_TAG, fileName, strerror(errno)); - goto fail; - } - newTagMap->mapLen = end; - - if (processFile(newTagMap) != 0) - goto fail; - - return newTagMap; - -fail: - android_closeEventTagMap(newTagMap); - if (fd >= 0) - close(fd); - return NULL; -} - -/* - * Close the map. - */ -void android_closeEventTagMap(EventTagMap* map) -{ - if (map == NULL) - return; - - munmap(map->mapAddr, map->mapLen); - free(map); -} - -/* - * Look up an entry in the map. - * - * The entries are sorted by tag number, so we can do a binary search. - */ -const char* android_lookupEventTag(const EventTagMap* map, int tag) -{ - int hi, lo, mid; - - lo = 0; - hi = map->numTags-1; - - while (lo <= hi) { - int cmp; - - mid = (lo+hi)/2; - cmp = map->tagArray[mid].tagIndex - tag; - if (cmp < 0) { - /* tag is bigger */ - lo = mid + 1; - } else if (cmp > 0) { - /* tag is smaller */ - hi = mid - 1; - } else { - /* found */ - return map->tagArray[mid].tagStr; - } - } - - return NULL; -} - - - -/* - * Determine whether "c" is a whitespace char. - */ -static inline int isCharWhitespace(char c) -{ - return (c == ' ' || c == '\n' || c == '\r' || c == '\t'); -} - -/* - * Determine whether "c" is a valid tag char. - */ -static inline int isCharValidTag(char c) -{ - return ((c >= 'A' && c <= 'Z') || - (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9') || - (c == '_')); -} - -/* - * Determine whether "c" is a valid decimal digit. - */ -static inline int isCharDigit(char c) -{ - return (c >= '0' && c <= '9'); -} - - -/* - * Crunch through the file, parsing the contents and creating a tag index. - */ -static int processFile(EventTagMap* map) -{ - EventTag* tagArray = NULL; - - /* get a tag count */ - map->numTags = countMapLines(map); - if (map->numTags < 0) - return -1; - - //printf("+++ found %d tags\n", map->numTags); - - /* allocate storage for the tag index array */ - map->tagArray = calloc(1, sizeof(EventTag) * map->numTags); - if (map->tagArray == NULL) - return -1; - - /* parse the file, null-terminating tag strings */ - if (parseMapLines(map) != 0) { - fprintf(stderr, "%s: file parse failed\n", OUT_TAG); - return -1; - } - - /* sort the tags and check for duplicates */ - if (sortTags(map) != 0) - return -1; - - return 0; -} - -/* - * Run through all lines in the file, determining whether they're blank, - * comments, or possibly have a tag entry. - * - * This is a very "loose" scan. We don't try to detect syntax errors here. - * The later pass is more careful, but the number of tags found there must - * match the number of tags found here. - * - * Returns the number of potential tag entries found. - */ -static int countMapLines(const EventTagMap* map) -{ - int numTags, unknown; - const char* cp; - const char* endp; - - cp = (const char*) map->mapAddr; - endp = cp + map->mapLen; - - numTags = 0; - unknown = 1; - while (cp < endp) { - if (*cp == '\n') { - unknown = 1; - } else if (unknown) { - if (isCharDigit(*cp)) { - /* looks like a tag to me */ - numTags++; - unknown = 0; - } else if (isCharWhitespace(*cp)) { - /* might be leading whitespace before tag num, keep going */ - } else { - /* assume comment; second pass can complain in detail */ - unknown = 0; - } - } else { - /* we've made up our mind; just scan to end of line */ - } - cp++; - } - - return numTags; -} - -/* - * Parse the tags out of the file. - */ -static int parseMapLines(EventTagMap* map) -{ - int tagNum, lineStart, lineNum; - char* cp; - char* endp; - - cp = (char*) map->mapAddr; - endp = cp + map->mapLen; - - /* insist on EOL at EOF; simplifies parsing and null-termination */ - if (*(endp-1) != '\n') { - fprintf(stderr, "%s: map file missing EOL on last line\n", OUT_TAG); - return -1; - } - - tagNum = 0; - lineStart = 1; - lineNum = 1; - while (cp < endp) { - //printf("{%02x}", *cp); fflush(stdout); - if (*cp == '\n') { - lineStart = 1; - lineNum++; - } else if (lineStart) { - if (*cp == '#') { - /* comment; just scan to end */ - lineStart = 0; - } else if (isCharDigit(*cp)) { - /* looks like a tag; scan it out */ - if (tagNum >= map->numTags) { - fprintf(stderr, - "%s: more tags than expected (%d)\n", OUT_TAG, tagNum); - return -1; - } - if (scanTagLine(&cp, &map->tagArray[tagNum], lineNum) != 0) - return -1; - tagNum++; - lineNum++; // we eat the '\n' - /* leave lineStart==1 */ - } else if (isCharWhitespace(*cp)) { - /* looks like leading whitespace; keep scanning */ - } else { - fprintf(stderr, - "%s: unexpected chars (0x%02x) in tag number on line %d\n", - OUT_TAG, *cp, lineNum); - return -1; - } - } else { - /* this is a blank or comment line */ - } - cp++; - } - - if (tagNum != map->numTags) { - fprintf(stderr, "%s: parsed %d tags, expected %d\n", - OUT_TAG, tagNum, map->numTags); - return -1; - } - - return 0; -} - -/* - * Scan one tag line. - * - * "*pData" should be pointing to the first digit in the tag number. On - * successful return, it will be pointing to the last character in the - * tag line (i.e. the character before the start of the next line). - * - * Returns 0 on success, nonzero on failure. - */ -static int scanTagLine(char** pData, EventTag* tag, int lineNum) -{ - char* cp = *pData; - char* startp; - char* endp; - unsigned long val; - - startp = cp; - while (isCharDigit(*++cp)) - ; - *cp = '\0'; - - val = strtoul(startp, &endp, 10); - assert(endp == cp); - if (endp != cp) - fprintf(stderr, "ARRRRGH\n"); - - tag->tagIndex = val; - - while (*++cp != '\n' && isCharWhitespace(*cp)) - ; - - if (*cp == '\n') { - fprintf(stderr, - "%s: missing tag string on line %d\n", OUT_TAG, lineNum); - return -1; - } - - tag->tagStr = cp; - - while (isCharValidTag(*++cp)) - ; - - if (*cp == '\n') { - /* null terminate and return */ - *cp = '\0'; - } else if (isCharWhitespace(*cp)) { - /* CRLF or trailin spaces; zap this char, then scan for the '\n' */ - *cp = '\0'; - - /* just ignore the rest of the line till \n - TODO: read the tag description that follows the tag name - */ - while (*++cp != '\n') { - } - } else { - fprintf(stderr, - "%s: invalid tag chars on line %d\n", OUT_TAG, lineNum); - return -1; - } - - *pData = cp; - - //printf("+++ Line %d: got %d '%s'\n", lineNum, tag->tagIndex, tag->tagStr); - return 0; -} - -/* - * Compare two EventTags. - */ -static int compareEventTags(const void* v1, const void* v2) -{ - const EventTag* tag1 = (const EventTag*) v1; - const EventTag* tag2 = (const EventTag*) v2; - - return tag1->tagIndex - tag2->tagIndex; -} - -/* - * Sort the EventTag array so we can do fast lookups by tag index. After - * the sort we do a quick check for duplicate tag indices. - * - * Returns 0 on success. - */ -static int sortTags(EventTagMap* map) -{ - int i; - - qsort(map->tagArray, map->numTags, sizeof(EventTag), compareEventTags); - - for (i = 1; i < map->numTags; i++) { - if (map->tagArray[i].tagIndex == map->tagArray[i-1].tagIndex) { - fprintf(stderr, "%s: duplicate tag entries (%d:%s and %d:%s)\n", - OUT_TAG, - map->tagArray[i].tagIndex, map->tagArray[i].tagStr, - map->tagArray[i-1].tagIndex, map->tagArray[i-1].tagStr); - return -1; - } - } - - return 0; -} - -/* - * Dump the tag array for debugging. - */ -static void dumpTags(const EventTagMap* map) -{ - int i; - - for (i = 0; i < map->numTags; i++) { - const EventTag* tag = &map->tagArray[i]; - printf(" %3d: %6d '%s'\n", i, tag->tagIndex, tag->tagStr); - } -} - diff --git a/liblog/fake_log_device.c b/liblog/fake_log_device.c deleted file mode 100644 index d9d67b4730d79d60153647d221c18e55b5ce69c8..0000000000000000000000000000000000000000 --- a/liblog/fake_log_device.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -/* - * Intercepts log messages intended for the Android log device. - * When running in the context of the simulator, the messages are - * passed on to the underlying (fake) log device. When not in the - * simulator, messages are printed to stderr. - */ -#include "cutils/logd.h" - -#include <stdlib.h> -#include <string.h> -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> - -#ifdef HAVE_PTHREADS -#include <pthread.h> -#endif - -#define kMaxTagLen 16 /* from the long-dead utils/Log.cpp */ - -#define kTagSetSize 16 /* arbitrary */ - -#if 0 -#define TRACE(...) printf("fake_log_device: " __VA_ARGS__) -#else -#define TRACE(...) ((void)0) -#endif - -/* from the long-dead utils/Log.cpp */ -typedef enum { - FORMAT_OFF = 0, - FORMAT_BRIEF, - FORMAT_PROCESS, - FORMAT_TAG, - FORMAT_THREAD, - FORMAT_RAW, - FORMAT_TIME, - FORMAT_THREADTIME, - FORMAT_LONG -} LogFormat; - - -/* - * Log driver state. - */ -typedef struct LogState { - /* the fake fd that's seen by the user */ - int fakeFd; - - /* a printable name for this fake device */ - char *debugName; - - /* nonzero if this is a binary log */ - int isBinary; - - /* global minimum priority */ - int globalMinPriority; - - /* output format */ - LogFormat outputFormat; - - /* tags and priorities */ - struct { - char tag[kMaxTagLen]; - int minPriority; - } tagSet[kTagSetSize]; -} LogState; - - -#ifdef HAVE_PTHREADS -/* - * Locking. Since we're emulating a device, we need to be prepared - * to have multiple callers at the same time. This lock is used - * to both protect the fd list and to prevent LogStates from being - * freed out from under a user. - */ -static pthread_mutex_t fakeLogDeviceLock = PTHREAD_MUTEX_INITIALIZER; - -static void lock() -{ - pthread_mutex_lock(&fakeLogDeviceLock); -} - -static void unlock() -{ - pthread_mutex_unlock(&fakeLogDeviceLock); -} -#else // !HAVE_PTHREADS -#define lock() ((void)0) -#define unlock() ((void)0) -#endif // !HAVE_PTHREADS - - -/* - * File descriptor management. - */ -#define FAKE_FD_BASE 10000 -#define MAX_OPEN_LOGS 16 -static LogState *openLogTable[MAX_OPEN_LOGS]; - -/* - * Allocate an fd and associate a new LogState with it. - * The fd is available via the fakeFd field of the return value. - */ -static LogState *createLogState() -{ - size_t i; - - for (i = 0; i < sizeof(openLogTable); i++) { - if (openLogTable[i] == NULL) { - openLogTable[i] = calloc(1, sizeof(LogState)); - openLogTable[i]->fakeFd = FAKE_FD_BASE + i; - return openLogTable[i]; - } - } - return NULL; -} - -/* - * Translate an fd to a LogState. - */ -static LogState *fdToLogState(int fd) -{ - if (fd >= FAKE_FD_BASE && fd < FAKE_FD_BASE + MAX_OPEN_LOGS) { - return openLogTable[fd - FAKE_FD_BASE]; - } - return NULL; -} - -/* - * Unregister the fake fd and free the memory it pointed to. - */ -static void deleteFakeFd(int fd) -{ - LogState *ls; - - lock(); - - ls = fdToLogState(fd); - if (ls != NULL) { - openLogTable[fd - FAKE_FD_BASE] = NULL; - free(ls->debugName); - free(ls); - } - - unlock(); -} - -/* - * Configure logging based on ANDROID_LOG_TAGS environment variable. We - * need to parse a string that looks like - * - * *:v jdwp:d dalvikvm:d dalvikvm-gc:i dalvikvmi:i - * - * The tag (or '*' for the global level) comes first, followed by a colon - * and a letter indicating the minimum priority level we're expected to log. - * This can be used to reveal or conceal logs with specific tags. - * - * We also want to check ANDROID_PRINTF_LOG to determine how the output - * will look. - */ -static void configureInitialState(const char* pathName, LogState* logState) -{ - static const int kDevLogLen = sizeof("/dev/log/") - 1; - - logState->debugName = strdup(pathName); - - /* identify binary logs */ - if (strcmp(pathName + kDevLogLen, "events") == 0) { - logState->isBinary = 1; - } - - /* global min priority defaults to "info" level */ - logState->globalMinPriority = ANDROID_LOG_INFO; - - /* - * This is based on the the long-dead utils/Log.cpp code. - */ - const char* tags = getenv("ANDROID_LOG_TAGS"); - TRACE("Found ANDROID_LOG_TAGS='%s'\n", tags); - if (tags != NULL) { - int entry = 0; - - while (*tags != '\0') { - char tagName[kMaxTagLen]; - int i, minPrio; - - while (isspace(*tags)) - tags++; - - i = 0; - while (*tags != '\0' && !isspace(*tags) && *tags != ':' && - i < kMaxTagLen) - { - tagName[i++] = *tags++; - } - if (i == kMaxTagLen) { - TRACE("ERROR: env tag too long (%d chars max)\n", kMaxTagLen-1); - return; - } - tagName[i] = '\0'; - - /* default priority, if there's no ":" part; also zero out '*' */ - minPrio = ANDROID_LOG_VERBOSE; - if (tagName[0] == '*' && tagName[1] == '\0') { - minPrio = ANDROID_LOG_DEBUG; - tagName[0] = '\0'; - } - - if (*tags == ':') { - tags++; - if (*tags >= '0' && *tags <= '9') { - if (*tags >= ('0' + ANDROID_LOG_SILENT)) - minPrio = ANDROID_LOG_VERBOSE; - else - minPrio = *tags - '\0'; - } else { - switch (*tags) { - case 'v': minPrio = ANDROID_LOG_VERBOSE; break; - case 'd': minPrio = ANDROID_LOG_DEBUG; break; - case 'i': minPrio = ANDROID_LOG_INFO; break; - case 'w': minPrio = ANDROID_LOG_WARN; break; - case 'e': minPrio = ANDROID_LOG_ERROR; break; - case 'f': minPrio = ANDROID_LOG_FATAL; break; - case 's': minPrio = ANDROID_LOG_SILENT; break; - default: minPrio = ANDROID_LOG_DEFAULT; break; - } - } - - tags++; - if (*tags != '\0' && !isspace(*tags)) { - TRACE("ERROR: garbage in tag env; expected whitespace\n"); - TRACE(" env='%s'\n", tags); - return; - } - } - - if (tagName[0] == 0) { - logState->globalMinPriority = minPrio; - TRACE("+++ global min prio %d\n", logState->globalMinPriority); - } else { - logState->tagSet[entry].minPriority = minPrio; - strcpy(logState->tagSet[entry].tag, tagName); - TRACE("+++ entry %d: %s:%d\n", - entry, - logState->tagSet[entry].tag, - logState->tagSet[entry].minPriority); - entry++; - } - } - } - - - /* - * Taken from the long-dead utils/Log.cpp - */ - const char* fstr = getenv("ANDROID_PRINTF_LOG"); - LogFormat format; - if (fstr == NULL) { - format = FORMAT_BRIEF; - } else { - if (strcmp(fstr, "brief") == 0) - format = FORMAT_BRIEF; - else if (strcmp(fstr, "process") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "tag") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "thread") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "raw") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "time") == 0) - format = FORMAT_PROCESS; - else if (strcmp(fstr, "long") == 0) - format = FORMAT_PROCESS; - else - format = (LogFormat) atoi(fstr); // really?! - } - - logState->outputFormat = format; -} - -/* - * Return a human-readable string for the priority level. Always returns - * a valid string. - */ -static const char* getPriorityString(int priority) -{ - /* the first character of each string should be unique */ - static const char* priorityStrings[] = { - "Verbose", "Debug", "Info", "Warn", "Error", "Assert" - }; - int idx; - - idx = (int) priority - (int) ANDROID_LOG_VERBOSE; - if (idx < 0 || - idx >= (int) (sizeof(priorityStrings) / sizeof(priorityStrings[0]))) - return "?unknown?"; - return priorityStrings[idx]; -} - -#ifndef HAVE_WRITEV -/* - * Some platforms like WIN32 do not have writev(). - * Make up something to replace it. - */ -static ssize_t fake_writev(int fd, const struct iovec *iov, int iovcnt) { - int result = 0; - struct iovec* end = iov + iovcnt; - for (; iov < end; iov++) { - int w = write(fd, iov->iov_base, iov->iov_len); - if (w != iov->iov_len) { - if (w < 0) - return w; - return result + w; - } - result += w; - } - return result; -} - -#define writev fake_writev -#endif - - -/* - * Write a filtered log message to stderr. - * - * Log format parsing taken from the long-dead utils/Log.cpp. - */ -static void showLog(LogState *state, - int logPrio, const char* tag, const char* msg) -{ -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - char timeBuf[32]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - time_t when; - pid_t pid, tid; - - TRACE("LOG %d: %s %s", logPrio, tag, msg); - - priChar = getPriorityString(logPrio)[0]; - when = time(NULL); - pid = tid = getpid(); // find gettid()? - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - */ -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&when, &tmBuf); -#else - ptm = localtime(&when); -#endif - //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm); - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - - /* - * Construct a buffer containing the log header and log message. - */ - size_t prefixLen, suffixLen; - - switch (state->outputFormat) { - case FORMAT_TAG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s: ", priChar, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_PROCESS: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d) ", priChar, pid); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), - " (%s)\n", tag); - break; - case FORMAT_THREAD: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d:%p) ", priChar, pid, (void*)tid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_RAW: - prefixBuf[0] = 0; prefixLen = 0; - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_TIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s %-8s\n\t", timeBuf, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_THREADTIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s %5d %5d %c %-8s \n\t", timeBuf, pid, tid, priChar, tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_LONG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "[ %s %5d:%p %c/%-8s ]\n", - timeBuf, pid, (void*)tid, priChar, tag); - strcpy(suffixBuf, "\n\n"); suffixLen = 2; - break; - default: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s(%5d): ", priChar, tag, pid); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - } - - /* - * Figure out how many lines there will be. - */ - const char* end = msg + strlen(msg); - size_t numLines = 0; - const char* p = msg; - while (p < end) { - if (*p++ == '\n') numLines++; - } - if (p > msg && *(p-1) != '\n') numLines++; - - /* - * Create an array of iovecs large enough to write all of - * the lines with a prefix and a suffix. - */ - const size_t INLINE_VECS = 6; - struct iovec stackVec[INLINE_VECS]; - struct iovec* vec = stackVec; - - numLines *= 3; // 3 iovecs per line. - if (numLines > INLINE_VECS) { - vec = (struct iovec*)malloc(sizeof(struct iovec)*numLines); - if (vec == NULL) { - msg = "LOG: write failed, no memory"; - numLines = 3; - } - } - - /* - * Fill in the iovec pointers. - */ - p = msg; - struct iovec* v = vec; - int totalLen = 0; - while (p < end) { - if (prefixLen > 0) { - v->iov_base = prefixBuf; - v->iov_len = prefixLen; - totalLen += prefixLen; - v++; - } - const char* start = p; - while (p < end && *p != '\n') p++; - if ((p-start) > 0) { - v->iov_base = (void*)start; - v->iov_len = p-start; - totalLen += p-start; - v++; - } - if (*p == '\n') p++; - if (suffixLen > 0) { - v->iov_base = suffixBuf; - v->iov_len = suffixLen; - totalLen += suffixLen; - v++; - } - } - - /* - * Write the entire message to the log file with a single writev() call. - * We need to use this rather than a collection of printf()s on a FILE* - * because of multi-threading and multi-process issues. - * - * If the file was not opened with O_APPEND, this will produce interleaved - * output when called on the same file from multiple processes. - * - * If the file descriptor is actually a network socket, the writev() - * call may return with a partial write. Putting the writev() call in - * a loop can result in interleaved data. This can be alleviated - * somewhat by wrapping the writev call in the Mutex. - */ - - for(;;) { - int cc = writev(fileno(stderr), vec, v-vec); - - if (cc == totalLen) break; - - if (cc < 0) { - if(errno == EINTR) continue; - - /* can't really log the failure; for now, throw out a stderr */ - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - break; - } else { - /* shouldn't happen when writing to file or tty */ - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", cc, totalLen); - break; - } - } - - /* if we allocated storage for the iovecs, free it */ - if (vec != stackVec) - free(vec); -} - - -/* - * Receive a log message. We happen to know that "vector" has three parts: - * - * priority (1 byte) - * tag (N bytes -- null-terminated ASCII string) - * message (N bytes -- null-terminated ASCII string) - */ -static ssize_t logWritev(int fd, const struct iovec* vector, int count) -{ - LogState* state; - - /* Make sure that no-one frees the LogState while we're using it. - * Also guarantees that only one thread is in showLog() at a given - * time (if it matters). - */ - lock(); - - state = fdToLogState(fd); - if (state == NULL) { - errno = EBADF; - goto error; - } - - if (state->isBinary) { - TRACE("%s: ignoring binary log\n", state->debugName); - goto bail; - } - - if (count != 3) { - TRACE("%s: writevLog with count=%d not expected\n", - state->debugName, count); - goto error; - } - - /* pull out the three fields */ - int logPrio = *(const char*)vector[0].iov_base; - const char* tag = (const char*) vector[1].iov_base; - const char* msg = (const char*) vector[2].iov_base; - - /* see if this log tag is configured */ - int i; - int minPrio = state->globalMinPriority; - for (i = 0; i < kTagSetSize; i++) { - if (state->tagSet[i].minPriority == ANDROID_LOG_UNKNOWN) - break; /* reached end of configured values */ - - if (strcmp(state->tagSet[i].tag, tag) == 0) { - //TRACE("MATCH tag '%s'\n", tag); - minPrio = state->tagSet[i].minPriority; - break; - } - } - - if (logPrio >= minPrio) { - showLog(state, logPrio, tag, msg); - } else { - //TRACE("+++ NOLOG(%d): %s %s", logPrio, tag, msg); - } - -bail: - unlock(); - return vector[0].iov_len + vector[1].iov_len + vector[2].iov_len; -error: - unlock(); - return -1; -} - -/* - * Free up our state and close the fake descriptor. - */ -static int logClose(int fd) -{ - deleteFakeFd(fd); - return 0; -} - -/* - * Open a log output device and return a fake fd. - */ -static int logOpen(const char* pathName, int flags) -{ - LogState *logState; - int fd = -1; - - lock(); - - logState = createLogState(); - if (logState != NULL) { - configureInitialState(pathName, logState); - fd = logState->fakeFd; - } else { - errno = ENFILE; - } - - unlock(); - - return fd; -} - - -/* - * Runtime redirection. If this binary is running in the simulator, - * just pass log messages to the emulated device. If it's running - * outside of the simulator, write the log messages to stderr. - */ - -static int (*redirectOpen)(const char *pathName, int flags) = NULL; -static int (*redirectClose)(int fd) = NULL; -static ssize_t (*redirectWritev)(int fd, const struct iovec* vector, int count) - = NULL; - -static void setRedirects() -{ - const char *ws; - - /* Wrapsim sets this environment variable on children that it's - * created using its LD_PRELOAD wrapper. - */ - ws = getenv("ANDROID_WRAPSIM"); - if (ws != NULL && strcmp(ws, "1") == 0) { - /* We're running inside wrapsim, so we can just write to the device. */ - redirectOpen = (int (*)(const char *pathName, int flags))open; - redirectClose = close; - redirectWritev = writev; - } else { - /* There's no device to delegate to; handle the logging ourselves. */ - redirectOpen = logOpen; - redirectClose = logClose; - redirectWritev = logWritev; - } -} - -int fakeLogOpen(const char *pathName, int flags) -{ - if (redirectOpen == NULL) { - setRedirects(); - } - return redirectOpen(pathName, flags); -} - -int fakeLogClose(int fd) -{ - /* Assume that open() was called first. */ - return redirectClose(fd); -} - -ssize_t fakeLogWritev(int fd, const struct iovec* vector, int count) -{ - /* Assume that open() was called first. */ - return redirectWritev(fd, vector, count); -} diff --git a/liblog/logd_write.c b/liblog/logd_write.c deleted file mode 100644 index 80867d1d5ef17be33b1bb7aaee0878011df47f02..0000000000000000000000000000000000000000 --- a/liblog/logd_write.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2007 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include <time.h> -#include <stdio.h> -#ifdef HAVE_PTHREADS -#include <pthread.h> -#endif -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <stdlib.h> -#include <stdarg.h> - -#include <cutils/logger.h> -#include <cutils/logd.h> - -#define LOG_BUF_SIZE 1024 - -#if FAKE_LOG_DEVICE -// This will be defined when building for the host. -#define log_open(pathname, flags) fakeLogOpen(pathname, flags) -#define log_writev(filedes, vector, count) fakeLogWritev(filedes, vector, count) -#define log_close(filedes) fakeLogClose(filedes) -#else -#define log_open(pathname, flags) open(pathname, flags) -#define log_writev(filedes, vector, count) writev(filedes, vector, count) -#define log_close(filedes) close(filedes) -#endif - -typedef enum { - LOG_ID_MAIN = 0, - LOG_ID_RADIO, - LOG_ID_EVENTS, - LOG_ID_MAX -} log_id_t; - -static int __write_to_log_init(log_id_t, struct iovec *vec, size_t nr); -static int (*write_to_log)(log_id_t, struct iovec *vec, size_t nr) = - __write_to_log_init; -#ifdef HAVE_PTHREADS -static pthread_mutex_t log_init_lock = PTHREAD_MUTEX_INITIALIZER; -#endif - -static int log_fds[(int)LOG_ID_MAX] = { -1, -1, -1 }; - -/* - * This is used by the C++ code to decide if it should write logs through - * the C code. Basically, if /dev/log/... is available, we're running in - * the simulator rather than a desktop tool and want to use the device. - */ -static enum { - kLogUninitialized, kLogNotAvailable, kLogAvailable -} g_log_status = kLogUninitialized; -int __android_log_dev_available(void) -{ - if (g_log_status == kLogUninitialized) { - if (access("/dev/"LOGGER_LOG_MAIN, W_OK) == 0) - g_log_status = kLogAvailable; - else - g_log_status = kLogNotAvailable; - } - - return (g_log_status == kLogAvailable); -} - -static int __write_to_log_null(log_id_t log_fd, struct iovec *vec, size_t nr) -{ - return -1; -} - -static int __write_to_log_kernel(log_id_t log_id, struct iovec *vec, size_t nr) -{ - ssize_t ret; - int log_fd; - - if (/*(int)log_id >= 0 &&*/ (int)log_id < (int)LOG_ID_MAX) { - log_fd = log_fds[(int)log_id]; - } else { - return EBADF; - } - - do { - ret = log_writev(log_fd, vec, nr); - } while (ret < 0 && errno == EINTR); - - return ret; -} - -static int __write_to_log_init(log_id_t log_id, struct iovec *vec, size_t nr) -{ -#ifdef HAVE_PTHREADS - pthread_mutex_lock(&log_init_lock); -#endif - - if (write_to_log == __write_to_log_init) { - log_fds[LOG_ID_MAIN] = log_open("/dev/"LOGGER_LOG_MAIN, O_WRONLY); - log_fds[LOG_ID_RADIO] = log_open("/dev/"LOGGER_LOG_RADIO, O_WRONLY); - log_fds[LOG_ID_EVENTS] = log_open("/dev/"LOGGER_LOG_EVENTS, O_WRONLY); - - write_to_log = __write_to_log_kernel; - - if (log_fds[LOG_ID_MAIN] < 0 || log_fds[LOG_ID_RADIO] < 0 || - log_fds[LOG_ID_EVENTS] < 0) { - log_close(log_fds[LOG_ID_MAIN]); - log_close(log_fds[LOG_ID_RADIO]); - log_close(log_fds[LOG_ID_EVENTS]); - log_fds[LOG_ID_MAIN] = -1; - log_fds[LOG_ID_RADIO] = -1; - log_fds[LOG_ID_EVENTS] = -1; - write_to_log = __write_to_log_null; - } - } - -#ifdef HAVE_PTHREADS - pthread_mutex_unlock(&log_init_lock); -#endif - - return write_to_log(log_id, vec, nr); -} - -int __android_log_write(int prio, const char *tag, const char *msg) -{ - struct iovec vec[3]; - log_id_t log_id = LOG_ID_MAIN; - - if (!tag) - tag = ""; - - /* XXX: This needs to go! */ - if (!strcmp(tag, "HTC_RIL") || - !strcmp(tag, "RILJ") || - !strcmp(tag, "RILC") || - !strcmp(tag, "RILD") || - !strcmp(tag, "RIL") || - !strcmp(tag, "AT") || - !strcmp(tag, "GSM") || - !strcmp(tag, "STK")) - log_id = LOG_ID_RADIO; - - vec[0].iov_base = (unsigned char *) &prio; - vec[0].iov_len = 1; - vec[1].iov_base = (void *) tag; - vec[1].iov_len = strlen(tag) + 1; - vec[2].iov_base = (void *) msg; - vec[2].iov_len = strlen(msg) + 1; - - return write_to_log(log_id, vec, 3); -} - -int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap) -{ - char buf[LOG_BUF_SIZE]; - - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - - return __android_log_write(prio, tag, buf); -} - -int __android_log_print(int prio, const char *tag, const char *fmt, ...) -{ - va_list ap; - char buf[LOG_BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - - return __android_log_write(prio, tag, buf); -} - -void __android_log_assert(const char *cond, const char *tag, - const char *fmt, ...) -{ - va_list ap; - char buf[LOG_BUF_SIZE]; - - va_start(ap, fmt); - vsnprintf(buf, LOG_BUF_SIZE, fmt, ap); - va_end(ap); - - __android_log_write(ANDROID_LOG_FATAL, tag, buf); - - __builtin_trap(); /* trap so we have a chance to debug the situation */ -} - -int __android_log_bwrite(int32_t tag, const void *payload, size_t len) -{ - struct iovec vec[2]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = (void*)payload; - vec[1].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 2); -} - -/* - * Like __android_log_bwrite, but takes the type as well. Doesn't work - * for the general case where we're generating lists of stuff, but very - * handy if we just want to dump an integer into the log. - */ -int __android_log_btwrite(int32_t tag, char type, const void *payload, - size_t len) -{ - struct iovec vec[3]; - - vec[0].iov_base = &tag; - vec[0].iov_len = sizeof(tag); - vec[1].iov_base = &type; - vec[1].iov_len = sizeof(type); - vec[2].iov_base = (void*)payload; - vec[2].iov_len = len; - - return write_to_log(LOG_ID_EVENTS, vec, 3); -} diff --git a/liblog/logprint.c b/liblog/logprint.c deleted file mode 100644 index 2cf12545f164755cc4e78fb21f6af0bee3c48077..0000000000000000000000000000000000000000 --- a/liblog/logprint.c +++ /dev/null @@ -1,972 +0,0 @@ -/* //device/libs/cutils/logprint.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define _GNU_SOURCE /* for asprintf */ - -#include <ctype.h> -#include <stdio.h> -#include <errno.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <alloca.h> -#include <assert.h> -#include <arpa/inet.h> - -#include <cutils/logd.h> -#include <cutils/logprint.h> - -typedef struct FilterInfo_t { - char *mTag; - android_LogPriority mPri; - struct FilterInfo_t *p_next; -} FilterInfo; - -struct AndroidLogFormat_t { - android_LogPriority global_pri; - FilterInfo *filters; - AndroidLogPrintFormat format; -}; - -static FilterInfo * filterinfo_new(const char * tag, android_LogPriority pri) -{ - FilterInfo *p_ret; - - p_ret = (FilterInfo *)calloc(1, sizeof(FilterInfo)); - p_ret->mTag = strdup(tag); - p_ret->mPri = pri; - - return p_ret; -} - -static void filterinfo_free(FilterInfo *p_info) -{ - if (p_info == NULL) { - return; - } - - free(p_info->mTag); - p_info->mTag = NULL; -} - -/* - * Note: also accepts 0-9 priorities - * returns ANDROID_LOG_UNKNOWN if the character is unrecognized - */ -static android_LogPriority filterCharToPri (char c) -{ - android_LogPriority pri; - - c = tolower(c); - - if (c >= '0' && c <= '9') { - if (c >= ('0'+ANDROID_LOG_SILENT)) { - pri = ANDROID_LOG_VERBOSE; - } else { - pri = (android_LogPriority)(c - '0'); - } - } else if (c == 'v') { - pri = ANDROID_LOG_VERBOSE; - } else if (c == 'd') { - pri = ANDROID_LOG_DEBUG; - } else if (c == 'i') { - pri = ANDROID_LOG_INFO; - } else if (c == 'w') { - pri = ANDROID_LOG_WARN; - } else if (c == 'e') { - pri = ANDROID_LOG_ERROR; - } else if (c == 'f') { - pri = ANDROID_LOG_FATAL; - } else if (c == 's') { - pri = ANDROID_LOG_SILENT; - } else if (c == '*') { - pri = ANDROID_LOG_DEFAULT; - } else { - pri = ANDROID_LOG_UNKNOWN; - } - - return pri; -} - -static char filterPriToChar (android_LogPriority pri) -{ - switch (pri) { - case ANDROID_LOG_VERBOSE: return 'V'; - case ANDROID_LOG_DEBUG: return 'D'; - case ANDROID_LOG_INFO: return 'I'; - case ANDROID_LOG_WARN: return 'W'; - case ANDROID_LOG_ERROR: return 'E'; - case ANDROID_LOG_FATAL: return 'F'; - case ANDROID_LOG_SILENT: return 'S'; - - case ANDROID_LOG_DEFAULT: - case ANDROID_LOG_UNKNOWN: - default: return '?'; - } -} - -static android_LogPriority filterPriForTag( - AndroidLogFormat *p_format, const char *tag) -{ - FilterInfo *p_curFilter; - - for (p_curFilter = p_format->filters - ; p_curFilter != NULL - ; p_curFilter = p_curFilter->p_next - ) { - if (0 == strcmp(tag, p_curFilter->mTag)) { - if (p_curFilter->mPri == ANDROID_LOG_DEFAULT) { - return p_format->global_pri; - } else { - return p_curFilter->mPri; - } - } - } - - return p_format->global_pri; -} - -/** for debugging */ -static void dumpFilters(AndroidLogFormat *p_format) -{ - FilterInfo *p_fi; - - for (p_fi = p_format->filters ; p_fi != NULL ; p_fi = p_fi->p_next) { - char cPri = filterPriToChar(p_fi->mPri); - if (p_fi->mPri == ANDROID_LOG_DEFAULT) { - cPri = filterPriToChar(p_format->global_pri); - } - fprintf(stderr,"%s:%c\n", p_fi->mTag, cPri); - } - - fprintf(stderr,"*:%c\n", filterPriToChar(p_format->global_pri)); - -} - -/** - * returns 1 if this log line should be printed based on its priority - * and tag, and 0 if it should not - */ -int android_log_shouldPrintLine ( - AndroidLogFormat *p_format, const char *tag, android_LogPriority pri) -{ - return pri >= filterPriForTag(p_format, tag); -} - -AndroidLogFormat *android_log_format_new() -{ - AndroidLogFormat *p_ret; - - p_ret = calloc(1, sizeof(AndroidLogFormat)); - - p_ret->global_pri = ANDROID_LOG_VERBOSE; - p_ret->format = FORMAT_BRIEF; - - return p_ret; -} - -void android_log_format_free(AndroidLogFormat *p_format) -{ - FilterInfo *p_info, *p_info_old; - - p_info = p_format->filters; - - while (p_info != NULL) { - p_info_old = p_info; - p_info = p_info->p_next; - - free(p_info_old); - } - - free(p_format); -} - - - -void android_log_setPrintFormat(AndroidLogFormat *p_format, - AndroidLogPrintFormat format) -{ - p_format->format=format; -} - -/** - * Returns FORMAT_OFF on invalid string - */ -AndroidLogPrintFormat android_log_formatFromString(const char * formatString) -{ - static AndroidLogPrintFormat format; - - if (strcmp(formatString, "brief") == 0) format = FORMAT_BRIEF; - else if (strcmp(formatString, "process") == 0) format = FORMAT_PROCESS; - else if (strcmp(formatString, "tag") == 0) format = FORMAT_TAG; - else if (strcmp(formatString, "thread") == 0) format = FORMAT_THREAD; - else if (strcmp(formatString, "raw") == 0) format = FORMAT_RAW; - else if (strcmp(formatString, "time") == 0) format = FORMAT_TIME; - else if (strcmp(formatString, "threadtime") == 0) format = FORMAT_THREADTIME; - else if (strcmp(formatString, "long") == 0) format = FORMAT_LONG; - else format = FORMAT_OFF; - - return format; -} - -/** - * filterExpression: a single filter expression - * eg "AT:d" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - */ - -int android_log_addFilterRule(AndroidLogFormat *p_format, - const char *filterExpression) -{ - size_t i=0; - size_t tagNameLength; - android_LogPriority pri = ANDROID_LOG_DEFAULT; - - tagNameLength = strcspn(filterExpression, ":"); - - if (tagNameLength == 0) { - goto error; - } - - if(filterExpression[tagNameLength] == ':') { - pri = filterCharToPri(filterExpression[tagNameLength+1]); - - if (pri == ANDROID_LOG_UNKNOWN) { - goto error; - } - } - - if(0 == strncmp("*", filterExpression, tagNameLength)) { - // This filter expression refers to the global filter - // The default level for this is DEBUG if the priority - // is unspecified - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_DEBUG; - } - - p_format->global_pri = pri; - } else { - // for filter expressions that don't refer to the global - // filter, the default is verbose if the priority is unspecified - if (pri == ANDROID_LOG_DEFAULT) { - pri = ANDROID_LOG_VERBOSE; - } - - char *tagName; - -// Presently HAVE_STRNDUP is never defined, so the second case is always taken -// Darwin doesn't have strnup, everything else does -#ifdef HAVE_STRNDUP - tagName = strndup(filterExpression, tagNameLength); -#else - //a few extra bytes copied... - tagName = strdup(filterExpression); - tagName[tagNameLength] = '\0'; -#endif /*HAVE_STRNDUP*/ - - FilterInfo *p_fi = filterinfo_new(tagName, pri); - free(tagName); - - p_fi->p_next = p_format->filters; - p_format->filters = p_fi; - } - - return 0; -error: - return -1; -} - - -/** - * filterString: a comma/whitespace-separated set of filter expressions - * - * eg "AT:d *:i" - * - * returns 0 on success and -1 on invalid expression - * - * Assumes single threaded execution - * - */ - -int android_log_addFilterString(AndroidLogFormat *p_format, - const char *filterString) -{ - char *filterStringCopy = strdup (filterString); - char *p_cur = filterStringCopy; - char *p_ret; - int err; - - // Yes, I'm using strsep - while (NULL != (p_ret = strsep(&p_cur, " \t,"))) { - // ignore whitespace-only entries - if(p_ret[0] != '\0') { - err = android_log_addFilterRule(p_format, p_ret); - - if (err < 0) { - goto error; - } - } - } - - free (filterStringCopy); - return 0; -error: - free (filterStringCopy); - return -1; -} - -static inline char * strip_end(char *str) -{ - char *end = str + strlen(str) - 1; - - while (end >= str && isspace(*end)) - *end-- = '\0'; - return str; -} - -/** - * Splits a wire-format buffer into an AndroidLogEntry - * entry allocated by caller. Pointers will point directly into buf - * - * Returns 0 on success and -1 on invalid wire format (entry will be - * in unspecified state) - */ -int android_log_processLogBuffer(struct logger_entry *buf, - AndroidLogEntry *entry) -{ - size_t tag_len; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->priority = buf->msg[0]; - entry->pid = buf->pid; - entry->tid = buf->tid; - entry->tag = buf->msg + 1; - tag_len = strlen(entry->tag); - entry->messageLen = buf->len - tag_len - 3; - entry->message = entry->tag + tag_len + 1; - - return 0; -} - -/* - * Extract a 4-byte value from a byte stream. - */ -static inline uint32_t get4LE(const uint8_t* src) -{ - return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); -} - -/* - * Extract an 8-byte value from a byte stream. - */ -static inline uint64_t get8LE(const uint8_t* src) -{ - uint32_t low, high; - - low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); - high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24); - return ((long long) high << 32) | (long long) low; -} - - -/* - * Recursively convert binary log data to printable form. - * - * This needs to be recursive because you can have lists of lists. - * - * If we run out of room, we stop processing immediately. It's important - * for us to check for space on every output element to avoid producing - * garbled output. - * - * Returns 0 on success, 1 on buffer full, -1 on failure. - */ -static int android_log_printBinaryEvent(const unsigned char** pEventData, - size_t* pEventDataLen, char** pOutBuf, size_t* pOutBufLen) -{ - const unsigned char* eventData = *pEventData; - size_t eventDataLen = *pEventDataLen; - char* outBuf = *pOutBuf; - size_t outBufLen = *pOutBufLen; - unsigned char type; - size_t outCount; - int result = 0; - - if (eventDataLen < 1) - return -1; - type = *eventData++; - eventDataLen--; - - //fprintf(stderr, "--- type=%d (rem len=%d)\n", type, eventDataLen); - - switch (type) { - case EVENT_TYPE_INT: - /* 32-bit signed int */ - { - int ival; - - if (eventDataLen < 4) - return -1; - ival = get4LE(eventData); - eventData += 4; - eventDataLen -= 4; - - outCount = snprintf(outBuf, outBufLen, "%d", ival); - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else { - /* halt output */ - goto no_room; - } - } - break; - case EVENT_TYPE_LONG: - /* 64-bit signed long */ - { - long long lval; - - if (eventDataLen < 8) - return -1; - lval = get8LE(eventData); - eventData += 8; - eventDataLen -= 8; - - outCount = snprintf(outBuf, outBufLen, "%lld", lval); - if (outCount < outBufLen) { - outBuf += outCount; - outBufLen -= outCount; - } else { - /* halt output */ - goto no_room; - } - } - break; - case EVENT_TYPE_STRING: - /* UTF-8 chars, not NULL-terminated */ - { - unsigned int strLen; - - if (eventDataLen < 4) - return -1; - strLen = get4LE(eventData); - eventData += 4; - eventDataLen -= 4; - - if (eventDataLen < strLen) - return -1; - - if (strLen < outBufLen) { - memcpy(outBuf, eventData, strLen); - outBuf += strLen; - outBufLen -= strLen; - } else if (outBufLen > 0) { - /* copy what we can */ - memcpy(outBuf, eventData, outBufLen); - outBuf += outBufLen; - outBufLen -= outBufLen; - goto no_room; - } - eventData += strLen; - eventDataLen -= strLen; - break; - } - case EVENT_TYPE_LIST: - /* N items, all different types */ - { - unsigned char count; - int i; - - if (eventDataLen < 1) - return -1; - - count = *eventData++; - eventDataLen--; - - if (outBufLen > 0) { - *outBuf++ = '['; - outBufLen--; - } else { - goto no_room; - } - - for (i = 0; i < count; i++) { - result = android_log_printBinaryEvent(&eventData, &eventDataLen, - &outBuf, &outBufLen); - if (result != 0) - goto bail; - - if (i < count-1) { - if (outBufLen > 0) { - *outBuf++ = ','; - outBufLen--; - } else { - goto no_room; - } - } - } - - if (outBufLen > 0) { - *outBuf++ = ']'; - outBufLen--; - } else { - goto no_room; - } - } - break; - default: - fprintf(stderr, "Unknown binary event type %d\n", type); - return -1; - } - -bail: - *pEventData = eventData; - *pEventDataLen = eventDataLen; - *pOutBuf = outBuf; - *pOutBufLen = outBufLen; - return result; - -no_room: - result = 1; - goto bail; -} - -/** - * Convert a binary log entry to ASCII form. - * - * For convenience we mimic the processLogBuffer API. There is no - * pre-defined output length for the binary data, since we're free to format - * it however we choose, which means we can't really use a fixed-size buffer - * here. - */ -int android_log_processBinaryLogBuffer(struct logger_entry *buf, - AndroidLogEntry *entry, const EventTagMap* map, char* messageBuf, - int messageBufLen) -{ - size_t inCount; - unsigned int tagIndex; - const unsigned char* eventData; - - entry->tv_sec = buf->sec; - entry->tv_nsec = buf->nsec; - entry->priority = ANDROID_LOG_INFO; - entry->pid = buf->pid; - entry->tid = buf->tid; - - /* - * Pull the tag out. - */ - eventData = (const unsigned char*) buf->msg; - inCount = buf->len; - if (inCount < 4) - return -1; - tagIndex = get4LE(eventData); - eventData += 4; - inCount -= 4; - - if (map != NULL) { - entry->tag = android_lookupEventTag(map, tagIndex); - } else { - entry->tag = NULL; - } - - /* - * If we don't have a map, or didn't find the tag number in the map, - * stuff a generated tag value into the start of the output buffer and - * shift the buffer pointers down. - */ - if (entry->tag == NULL) { - int tagLen; - - tagLen = snprintf(messageBuf, messageBufLen, "[%d]", tagIndex); - entry->tag = messageBuf; - messageBuf += tagLen+1; - messageBufLen -= tagLen+1; - } - - /* - * Format the event log data into the buffer. - */ - char* outBuf = messageBuf; - size_t outRemaining = messageBufLen-1; /* leave one for nul byte */ - int result; - result = android_log_printBinaryEvent(&eventData, &inCount, &outBuf, - &outRemaining); - if (result < 0) { - fprintf(stderr, "Binary log entry conversion failed\n"); - return -1; - } else if (result == 1) { - if (outBuf > messageBuf) { - /* leave an indicator */ - *(outBuf-1) = '!'; - } else { - /* no room to output anything at all */ - *outBuf++ = '!'; - outRemaining--; - } - /* pretend we ate all the data */ - inCount = 0; - } - - /* eat the silly terminating '\n' */ - if (inCount == 1 && *eventData == '\n') { - eventData++; - inCount--; - } - - if (inCount != 0) { - fprintf(stderr, - "Warning: leftover binary log data (%d bytes)\n", inCount); - } - - /* - * Terminate the buffer. The NUL byte does not count as part of - * entry->messageLen. - */ - *outBuf = '\0'; - entry->messageLen = outBuf - messageBuf; - assert(entry->messageLen == (messageBufLen-1) - outRemaining); - - entry->message = messageBuf; - - return 0; -} - -/** - * Formats a log message into a buffer - * - * Uses defaultBuffer if it can, otherwise malloc()'s a new buffer - * If return value != defaultBuffer, caller must call free() - * Returns NULL on malloc error - */ - -char *android_log_formatLogLine ( - AndroidLogFormat *p_format, - char *defaultBuffer, - size_t defaultBufferSize, - const AndroidLogEntry *entry, - size_t *p_outLength) -{ -#if defined(HAVE_LOCALTIME_R) - struct tm tmBuf; -#endif - struct tm* ptm; - char timeBuf[32]; - char headerBuf[128]; - char prefixBuf[128], suffixBuf[128]; - char priChar; - int prefixSuffixIsHeaderFooter = 0; - char * ret = NULL; - - priChar = filterPriToChar(entry->priority); - - /* - * Get the current date/time in pretty form - * - * It's often useful when examining a log with "less" to jump to - * a specific point in the file by searching for the date/time stamp. - * For this reason it's very annoying to have regexp meta characters - * in the time stamp. Don't use forward slashes, parenthesis, - * brackets, asterisks, or other special chars here. - */ -#if defined(HAVE_LOCALTIME_R) - ptm = localtime_r(&(entry->tv_sec), &tmBuf); -#else - ptm = localtime(&(entry->tv_sec)); -#endif - //strftime(timeBuf, sizeof(timeBuf), "%Y-%m-%d %H:%M:%S", ptm); - strftime(timeBuf, sizeof(timeBuf), "%m-%d %H:%M:%S", ptm); - - /* - * Construct a buffer containing the log header and log message. - */ - size_t prefixLen, suffixLen; - - switch (p_format->format) { - case FORMAT_TAG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s: ", priChar, entry->tag); - strcpy(suffixBuf, "\n"); suffixLen = 1; - break; - case FORMAT_PROCESS: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d) ", priChar, entry->pid); - suffixLen = snprintf(suffixBuf, sizeof(suffixBuf), - " (%s)\n", entry->tag); - break; - case FORMAT_THREAD: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c(%5d:%p) ", priChar, entry->pid, (void*)entry->tid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; - break; - case FORMAT_RAW: - prefixBuf[0] = 0; - prefixLen = 0; - strcpy(suffixBuf, "\n"); - suffixLen = 1; - break; - case FORMAT_TIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s.%03ld %c/%-8s(%5d): ", timeBuf, entry->tv_nsec / 1000000, - priChar, entry->tag, entry->pid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; - break; - case FORMAT_THREADTIME: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%s.%03ld %5d %5d %c %-8s: ", timeBuf, entry->tv_nsec / 1000000, - (int)entry->pid, (int)entry->tid, priChar, entry->tag); - strcpy(suffixBuf, "\n"); - suffixLen = 1; - break; - case FORMAT_LONG: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "[ %s.%03ld %5d:%p %c/%-8s ]\n", - timeBuf, entry->tv_nsec / 1000000, entry->pid, - (void*)entry->tid, priChar, entry->tag); - strcpy(suffixBuf, "\n\n"); - suffixLen = 2; - prefixSuffixIsHeaderFooter = 1; - break; - case FORMAT_BRIEF: - default: - prefixLen = snprintf(prefixBuf, sizeof(prefixBuf), - "%c/%-8s(%5d): ", priChar, entry->tag, entry->pid); - strcpy(suffixBuf, "\n"); - suffixLen = 1; - break; - } - - /* the following code is tragically unreadable */ - - size_t numLines; - size_t i; - char *p; - size_t bufferSize; - const char *pm; - - if (prefixSuffixIsHeaderFooter) { - // we're just wrapping message with a header/footer - numLines = 1; - } else { - pm = entry->message; - numLines = 0; - - // The line-end finding here must match the line-end finding - // in for ( ... numLines...) loop below - while (pm < (entry->message + entry->messageLen)) { - if (*pm++ == '\n') numLines++; - } - // plus one line for anything not newline-terminated at the end - if (pm > entry->message && *(pm-1) != '\n') numLines++; - } - - // this is an upper bound--newlines in message may be counted - // extraneously - bufferSize = (numLines * (prefixLen + suffixLen)) + entry->messageLen + 1; - - if (defaultBufferSize >= bufferSize) { - ret = defaultBuffer; - } else { - ret = (char *)malloc(bufferSize); - - if (ret == NULL) { - return ret; - } - } - - ret[0] = '\0'; /* to start strcat off */ - - p = ret; - pm = entry->message; - - if (prefixSuffixIsHeaderFooter) { - strcat(p, prefixBuf); - p += prefixLen; - strncat(p, entry->message, entry->messageLen); - p += entry->messageLen; - strcat(p, suffixBuf); - p += suffixLen; - } else { - while(pm < (entry->message + entry->messageLen)) { - const char *lineStart; - size_t lineLen; - - lineStart = pm; - - // Find the next end-of-line in message - while (pm < (entry->message + entry->messageLen) - && *pm != '\n') pm++; - lineLen = pm - lineStart; - - strcat(p, prefixBuf); - p += prefixLen; - strncat(p, lineStart, lineLen); - p += lineLen; - strcat(p, suffixBuf); - p += suffixLen; - - if (*pm == '\n') pm++; - } - } - - if (p_outLength != NULL) { - *p_outLength = p - ret; - } - - return ret; -} - -/** - * Either print or do not print log line, based on filter - * - * Returns count bytes written - */ - -int android_log_filterAndPrintLogLine( - AndroidLogFormat *p_format, - int fd, - const AndroidLogEntry *entry) -{ - int ret; - char defaultBuffer[512]; - char *outBuffer = NULL; - size_t totalLen; - - if (0 == android_log_shouldPrintLine(p_format, entry->tag, - entry->priority)) { - return 0; - } - - outBuffer = android_log_formatLogLine(p_format, defaultBuffer, - sizeof(defaultBuffer), entry, &totalLen); - - if (!outBuffer) - return -1; - - do { - ret = write(fd, outBuffer, totalLen); - } while (ret < 0 && errno == EINTR); - - if (ret < 0) { - fprintf(stderr, "+++ LOG: write failed (errno=%d)\n", errno); - ret = 0; - goto done; - } - - if (((size_t)ret) < totalLen) { - fprintf(stderr, "+++ LOG: write partial (%d of %d)\n", ret, - (int)totalLen); - goto done; - } - -done: - if (outBuffer != defaultBuffer) { - free(outBuffer); - } - - return ret; -} - - - -void logprint_run_tests() -{ -#if 0 - - fprintf(stderr, "tests disabled\n"); - -#else - - int err; - const char *tag; - AndroidLogFormat *p_format; - - p_format = android_log_format_new(); - - fprintf(stderr, "running tests\n"); - - tag = "random"; - - android_log_addFilterRule(p_format,"*:i"); - - assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - android_log_addFilterRule(p_format, "*"); - assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:v"); - assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "*:i"); - assert (ANDROID_LOG_INFO == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - android_log_addFilterRule(p_format, "random"); - assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:v"); - assert (ANDROID_LOG_VERBOSE == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:d"); - assert (ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) > 0); - android_log_addFilterRule(p_format, "random:w"); - assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - android_log_addFilterRule(p_format, "crap:*"); - assert (ANDROID_LOG_VERBOSE== filterPriForTag(p_format, "crap")); - assert(android_log_shouldPrintLine(p_format, "crap", ANDROID_LOG_VERBOSE) > 0); - - // invalid expression - err = android_log_addFilterRule(p_format, "random:z"); - assert (err < 0); - assert (ANDROID_LOG_WARN == filterPriForTag(p_format, "random")); - assert(android_log_shouldPrintLine(p_format, tag, ANDROID_LOG_DEBUG) == 0); - - // Issue #550946 - err = android_log_addFilterString(p_format, " "); - assert(err == 0); - assert(ANDROID_LOG_WARN == filterPriForTag(p_format, "random")); - - // note trailing space - err = android_log_addFilterString(p_format, "*:s random:d "); - assert(err == 0); - assert(ANDROID_LOG_DEBUG == filterPriForTag(p_format, "random")); - - err = android_log_addFilterString(p_format, "*:s random:z"); - assert(err < 0); - - -#if 0 - char *ret; - char defaultBuffer[512]; - - ret = android_log_formatLogLine(p_format, - defaultBuffer, sizeof(defaultBuffer), 0, ANDROID_LOG_ERROR, 123, - 123, 123, "random", "nofile", strlen("Hello"), "Hello", NULL); -#endif - - - fprintf(stderr, "tests complete\n"); -#endif -} diff --git a/libmincrypt/Android.mk b/libmincrypt/Android.mk deleted file mode 100644 index b09a9410c120b8e205efc9cfd827f46220a578aa..0000000000000000000000000000000000000000 --- a/libmincrypt/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -# Copyright 2008 The Android Open Source Project -# -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := libmincrypt -LOCAL_SRC_FILES := rsa.c sha.c -include $(BUILD_STATIC_LIBRARY) - -include $(CLEAR_VARS) - -LOCAL_MODULE := libmincrypt -LOCAL_SRC_FILES := rsa.c sha.c -include $(BUILD_HOST_STATIC_LIBRARY) - - -# TODO: drop the hyphen once these are checked in -include $(LOCAL_PATH)/tools/Android.mk diff --git a/libmincrypt/rsa.c b/libmincrypt/rsa.c deleted file mode 100644 index d7124fb65021b696e958c882ccba36654c98a1cb..0000000000000000000000000000000000000000 --- a/libmincrypt/rsa.c +++ /dev/null @@ -1,198 +0,0 @@ -/* rsa.c -** -** Copyright 2008, The Android Open Source Project -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * 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. -** * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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. -*/ - -#include "mincrypt/rsa.h" -#include "mincrypt/sha.h" - -/* a[] -= mod */ -static void subM(const RSAPublicKey *key, uint32_t *a) { - int64_t A = 0; - int i; - for (i = 0; i < key->len; ++i) { - A += (uint64_t)a[i] - key->n[i]; - a[i] = (uint32_t)A; - A >>= 32; - } -} - -/* return a[] >= mod */ -static int geM(const RSAPublicKey *key, const uint32_t *a) { - int i; - for (i = key->len; i;) { - --i; - if (a[i] < key->n[i]) return 0; - if (a[i] > key->n[i]) return 1; - } - return 1; /* equal */ -} - -/* montgomery c[] += a * b[] / R % mod */ -static void montMulAdd(const RSAPublicKey *key, - uint32_t* c, - const uint32_t a, - const uint32_t* b) { - uint64_t A = (uint64_t)a * b[0] + c[0]; - uint32_t d0 = (uint32_t)A * key->n0inv; - uint64_t B = (uint64_t)d0 * key->n[0] + (uint32_t)A; - int i; - - for (i = 1; i < key->len; ++i) { - A = (A >> 32) + (uint64_t)a * b[i] + c[i]; - B = (B >> 32) + (uint64_t)d0 * key->n[i] + (uint32_t)A; - c[i - 1] = (uint32_t)B; - } - - A = (A >> 32) + (B >> 32); - - c[i - 1] = (uint32_t)A; - - if (A >> 32) { - subM(key, c); - } -} - -/* montgomery c[] = a[] * b[] / R % mod */ -static void montMul(const RSAPublicKey *key, - uint32_t* c, - const uint32_t* a, - const uint32_t* b) { - int i; - for (i = 0; i < key->len; ++i) { - c[i] = 0; - } - for (i = 0; i < key->len; ++i) { - montMulAdd(key, c, a[i], b); - } -} - -/* In-place public exponentiation. -** Input and output big-endian byte array in inout. -*/ -static void modpow3(const RSAPublicKey *key, - uint8_t* inout) { - uint32_t a[RSANUMWORDS]; - uint32_t aR[RSANUMWORDS]; - uint32_t aaR[RSANUMWORDS]; - uint32_t *aaa = aR; /* Re-use location. */ - int i; - - /* Convert from big endian byte array to little endian word array. */ - for (i = 0; i < key->len; ++i) { - uint32_t tmp = - (inout[((key->len - 1 - i) * 4) + 0] << 24) | - (inout[((key->len - 1 - i) * 4) + 1] << 16) | - (inout[((key->len - 1 - i) * 4) + 2] << 8) | - (inout[((key->len - 1 - i) * 4) + 3] << 0); - a[i] = tmp; - } - - montMul(key, aR, a, key->rr); /* aR = a * RR / R mod M */ - montMul(key, aaR, aR, aR); /* aaR = aR * aR / R mod M */ - montMul(key, aaa, aaR, a); /* aaa = aaR * a / R mod M */ - - /* Make sure aaa < mod; aaa is at most 1x mod too large. */ - if (geM(key, aaa)) { - subM(key, aaa); - } - - /* Convert to bigendian byte array */ - for (i = key->len - 1; i >= 0; --i) { - uint32_t tmp = aaa[i]; - *inout++ = tmp >> 24; - *inout++ = tmp >> 16; - *inout++ = tmp >> 8; - *inout++ = tmp >> 0; - } -} - -/* Expected PKCS1.5 signature padding bytes, for a keytool RSA signature. -** Has the 0-length optional parameter encoded in the ASN1 (as opposed to the -** other flavor which omits the optional parameter entirely). This code does not -** accept signatures without the optional parameter. -*/ -static const uint8_t padding[RSANUMBYTES - SHA_DIGEST_SIZE] = { - 0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, - 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, - 0x30,0x21,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1a,0x05,0x00, - 0x04,0x14 -}; - -/* Verify a 2048 bit RSA PKCS1.5 signature against an expected SHA-1 hash. -** Returns 0 on failure, 1 on success. -*/ -int RSA_verify(const RSAPublicKey *key, - const uint8_t *signature, - const int len, - const uint8_t *sha) { - uint8_t buf[RSANUMBYTES]; - int i; - - if (key->len != RSANUMWORDS) { - return 0; /* Wrong key passed in. */ - } - - if (len != sizeof(buf)) { - return 0; /* Wrong input length. */ - } - - for (i = 0; i < len; ++i) { - buf[i] = signature[i]; - } - - modpow3(key, buf); - - /* Check pkcs1.5 padding bytes. */ - for (i = 0; i < (int) sizeof(padding); ++i) { - if (buf[i] != padding[i]) { - return 0; - } - } - - /* Check sha digest matches. */ - for (; i < len; ++i) { - if (buf[i] != *sha++) { - return 0; - } - } - - return 1; -} diff --git a/libmincrypt/sha.c b/libmincrypt/sha.c deleted file mode 100644 index d6120dae3c16288841e21d0f876ca197c98cc97e..0000000000000000000000000000000000000000 --- a/libmincrypt/sha.c +++ /dev/null @@ -1,142 +0,0 @@ -/* sha.c -** -** Copyright 2008, The Android Open Source Project -** -** Redistribution and use in source and binary forms, with or without -** modification, are permitted provided that the following conditions are met: -** * Redistributions of source code must retain the above copyright -** notice, this list of conditions and the following disclaimer. -** * 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. -** * Neither the name of Google Inc. 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 Google Inc. ``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 Google Inc. 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. -*/ - -#include "mincrypt/sha.h" - -#define rol(bits, value) (((value) << (bits)) | ((value) >> (32 - (bits)))) - -static void SHA1_transform(SHA_CTX *ctx) { - uint32_t W[80]; - uint32_t A, B, C, D, E; - uint8_t *p = ctx->buf; - int t; - - for(t = 0; t < 16; ++t) { - uint32_t tmp = *p++ << 24; - tmp |= *p++ << 16; - tmp |= *p++ << 8; - tmp |= *p++; - W[t] = tmp; - } - - for(; t < 80; t++) { - W[t] = rol(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); - } - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - - for(t = 0; t < 80; t++) { - uint32_t tmp = rol(5,A) + E + W[t]; - - if (t < 20) - tmp += (D^(B&(C^D))) + 0x5A827999; - else if ( t < 40) - tmp += (B^C^D) + 0x6ED9EBA1; - else if ( t < 60) - tmp += ((B&C)|(D&(B|C))) + 0x8F1BBCDC; - else - tmp += (B^C^D) + 0xCA62C1D6; - - E = D; - D = C; - C = rol(30,B); - B = A; - A = tmp; - } - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -void SHA_init(SHA_CTX *ctx) { - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; - ctx->count = 0; -} - -void SHA_update(SHA_CTX *ctx, const void *data, int len) { - int i = ctx->count % sizeof(ctx->buf); - const uint8_t* p = (const uint8_t*)data; - - ctx->count += len; - - while (len--) { - ctx->buf[i++] = *p++; - if (i == sizeof(ctx->buf)) { - SHA1_transform(ctx); - i = 0; - } - } -} -const uint8_t *SHA_final(SHA_CTX *ctx) { - uint8_t *p = ctx->buf; - uint64_t cnt = ctx->count * 8; - int i; - - SHA_update(ctx, (uint8_t*)"\x80", 1); - while ((ctx->count % sizeof(ctx->buf)) != (sizeof(ctx->buf) - 8)) { - SHA_update(ctx, (uint8_t*)"\0", 1); - } - for (i = 0; i < 8; ++i) { - uint8_t tmp = cnt >> ((7 - i) * 8); - SHA_update(ctx, &tmp, 1); - } - - for (i = 0; i < 5; i++) { - uint32_t tmp = ctx->state[i]; - *p++ = tmp >> 24; - *p++ = tmp >> 16; - *p++ = tmp >> 8; - *p++ = tmp >> 0; - } - - return ctx->buf; -} - -/* Convenience function */ -const uint8_t* SHA(const void *data, int len, uint8_t *digest) { - const uint8_t *p; - int i; - SHA_CTX ctx; - SHA_init(&ctx); - SHA_update(&ctx, data, len); - p = SHA_final(&ctx); - for (i = 0; i < SHA_DIGEST_SIZE; ++i) { - digest[i] = *p++; - } - return digest; -} diff --git a/libmincrypt/tools/Android.mk b/libmincrypt/tools/Android.mk deleted file mode 100644 index b61234a9ec5aa7145bb882e50493f803d0247a27..0000000000000000000000000000000000000000 --- a/libmincrypt/tools/Android.mk +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2008 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH := $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_MODULE := dumpkey -LOCAL_SRC_FILES := DumpPublicKey.java -LOCAL_JAR_MANIFEST := DumpPublicKey.mf -include $(BUILD_HOST_JAVA_LIBRARY) diff --git a/libmincrypt/tools/DumpPublicKey.java b/libmincrypt/tools/DumpPublicKey.java deleted file mode 100644 index c9e7e4d19caf922eedb52e7454978ed96c722663..0000000000000000000000000000000000000000 --- a/libmincrypt/tools/DumpPublicKey.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.dumpkey; - -import java.io.FileInputStream; -import java.math.BigInteger; -import java.security.cert.CertificateFactory; -import java.security.cert.Certificate; -import java.security.KeyStore; -import java.security.Key; -import java.security.PublicKey; -import java.security.interfaces.RSAPublicKey; -import sun.misc.BASE64Encoder; - -/** - * Command line tool to extract RSA public keys from X.509 certificates - * and output source code with data initializers for the keys. - * @hide - */ -class DumpPublicKey { - /** - * @param key to perform sanity checks on - * @throws Exception if the key has the wrong size or public exponent - */ - static void check(RSAPublicKey key) throws Exception { - BigInteger pubexp = key.getPublicExponent(); - BigInteger modulus = key.getModulus(); - - if (!pubexp.equals(BigInteger.valueOf(3))) - throw new Exception("Public exponent should be 3 but is " + - pubexp.toString(10) + "."); - - if (modulus.bitLength() != 2048) - throw new Exception("Modulus should be 2048 bits long but is " + - modulus.bitLength() + " bits."); - } - - /** - * @param key to output - * @return a C initializer representing this public key. - */ - static String print(RSAPublicKey key) throws Exception { - check(key); - - BigInteger N = key.getModulus(); - - StringBuilder result = new StringBuilder(); - - int nwords = N.bitLength() / 32; // # of 32 bit integers in modulus - - result.append("{"); - result.append(nwords); - - BigInteger B = BigInteger.valueOf(0x100000000L); // 2^32 - BigInteger N0inv = B.subtract(N.modInverse(B)); // -1 / N[0] mod 2^32 - - result.append(",0x"); - result.append(N0inv.toString(16)); - - BigInteger R = BigInteger.valueOf(2).pow(N.bitLength()); - BigInteger RR = R.multiply(R).mod(N); // 2^4096 mod N - - // Write out modulus as little endian array of integers. - result.append(",{"); - for (int i = 0; i < nwords; ++i) { - int n = N.mod(B).intValue(); - result.append(n); - - if (i != nwords - 1) { - result.append(","); - } - - N = N.divide(B); - } - result.append("}"); - - // Write R^2 as little endian array of integers. - result.append(",{"); - for (int i = 0; i < nwords; ++i) { - int rr = RR.mod(B).intValue(); - result.append(rr); - - if (i != nwords - 1) { - result.append(","); - } - - RR = RR.divide(B); - } - result.append("}"); - - result.append("}"); - return result.toString(); - } - - public static void main(String[] args) { - if (args.length < 1) { - System.err.println("Usage: DumpPublicKey certfile ... > source.c"); - System.exit(1); - } - try { - for (int i = 0; i < args.length; i++) { - FileInputStream input = new FileInputStream(args[i]); - CertificateFactory cf = CertificateFactory.getInstance("X.509"); - Certificate cert = cf.generateCertificate(input); - RSAPublicKey key = (RSAPublicKey) (cert.getPublicKey()); - check(key); - System.out.print(print(key)); - System.out.println(i < args.length - 1 ? "," : ""); - } - } catch (Exception e) { - e.printStackTrace(); - System.exit(1); - } - System.exit(0); - } -} diff --git a/libmincrypt/tools/DumpPublicKey.mf b/libmincrypt/tools/DumpPublicKey.mf deleted file mode 100644 index 7bb3bc88deefd2276cfc736f31c58d2ba0542fe0..0000000000000000000000000000000000000000 --- a/libmincrypt/tools/DumpPublicKey.mf +++ /dev/null @@ -1 +0,0 @@ -Main-Class: com.android.dumpkey.DumpPublicKey diff --git a/libnetutils/Android.mk b/libnetutils/Android.mk deleted file mode 100644 index 46102d55c16728326fff0e9375fd05ebcb7ddb77..0000000000000000000000000000000000000000 --- a/libnetutils/Android.mk +++ /dev/null @@ -1,23 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - dhcpclient.c \ - dhcpmsg.c \ - dhcp_utils.c \ - ifc_utils.c \ - packet.c - -LOCAL_SHARED_LIBRARIES := \ - libcutils - -# need "-lrt" on Linux simulator to pick up clock_gettime -ifeq ($(TARGET_SIMULATOR),true) - ifeq ($(HOST_OS),linux) - LOCAL_LDLIBS += -lrt -lpthread - endif -endif - -LOCAL_MODULE:= libnetutils - -include $(BUILD_SHARED_LIBRARY) diff --git a/libnetutils/dhcp_utils.c b/libnetutils/dhcp_utils.c deleted file mode 100644 index bad2e2ffda2a2859d4b1da2e7889d837b97e7d63..0000000000000000000000000000000000000000 --- a/libnetutils/dhcp_utils.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* Utilities for managing the dhcpcd DHCP client daemon */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <arpa/inet.h> -#include <netinet/in.h> - -#include <cutils/properties.h> - -static const char DAEMON_NAME[] = "dhcpcd"; -static const char DAEMON_PROP_NAME[] = "init.svc.dhcpcd"; -static const char DHCP_PROP_NAME_PREFIX[] = "dhcp"; -static const int NAP_TIME = 1; /* wait for 1 second at a time */ - /* when polling for property values */ -static char errmsg[100]; - -/* - * Wait for a system property to be assigned a specified value. - * If desired_value is NULL, then just wait for the property to - * be created with any value. maxwait is the maximum amount of - * time in seconds to wait before giving up. - */ -static int wait_for_property(const char *name, const char *desired_value, int maxwait) -{ - char value[PROPERTY_VALUE_MAX] = {'\0'}; - int maxnaps = maxwait / NAP_TIME; - - if (maxnaps < 1) { - maxnaps = 1; - } - - while (maxnaps-- > 0) { - usleep(1000000); - if (property_get(name, value, NULL)) { - if (desired_value == NULL || - strcmp(value, desired_value) == 0) { - return 0; - } - } - } - return -1; /* failure */ -} - -static void fill_ip_info(const char *interface, - in_addr_t *ipaddr, - in_addr_t *gateway, - in_addr_t *mask, - in_addr_t *dns1, - in_addr_t *dns2, - in_addr_t *server, - uint32_t *lease) -{ - char prop_name[PROPERTY_KEY_MAX]; - char prop_value[PROPERTY_VALUE_MAX]; - struct in_addr addr; - in_addr_t iaddr; - - snprintf(prop_name, sizeof(prop_name), "%s.%s.ipaddress", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *ipaddr = addr.s_addr; - } else { - *ipaddr = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.gateway", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *gateway = addr.s_addr; - } else { - *gateway = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.mask", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *mask = addr.s_addr; - } else { - *mask = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.dns1", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *dns1 = addr.s_addr; - } else { - *dns1 = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.dns2", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *dns2 = addr.s_addr; - } else { - *dns2 = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.server", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL) && inet_aton(prop_value, &addr)) { - *server = addr.s_addr; - } else { - *server = 0; - } - snprintf(prop_name, sizeof(prop_name), "%s.%s.leasetime", DHCP_PROP_NAME_PREFIX, interface); - if (property_get(prop_name, prop_value, NULL)) { - *lease = atol(prop_value); - } -} - -/* - * Start the dhcp client daemon, and wait for it to finish - * configuring the interface. - */ -int dhcp_do_request(const char *interface, - in_addr_t *ipaddr, - in_addr_t *gateway, - in_addr_t *mask, - in_addr_t *dns1, - in_addr_t *dns2, - in_addr_t *server, - uint32_t *lease) -{ - char result_prop_name[PROPERTY_KEY_MAX]; - char prop_value[PROPERTY_VALUE_MAX] = {'\0'}; - const char *ctrl_prop = "ctl.start"; - const char *desired_status = "running"; - - snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result", - DHCP_PROP_NAME_PREFIX, - interface); - /* Erase any previous setting of the dhcp result property */ - property_set(result_prop_name, ""); - - /* Start the daemon and wait until it's ready */ - property_set(ctrl_prop, DAEMON_NAME); - if (wait_for_property(DAEMON_PROP_NAME, desired_status, 10) < 0) { - snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for dhcpcd to start"); - return -1; - } - - /* Wait for the daemon to return a result */ - if (wait_for_property(result_prop_name, NULL, 30) < 0) { - snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP to finish"); - return -1; - } - - if (!property_get(result_prop_name, prop_value, NULL)) { - /* shouldn't ever happen, given the success of wait_for_property() */ - snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set"); - return -1; - } - if (strcmp(prop_value, "ok") == 0) { - fill_ip_info(interface, ipaddr, gateway, mask, dns1, dns2, server, lease); - return 0; - } else { - snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value); - return -1; - } -} - -/** - * Stop the DHCP client daemon. - */ -int dhcp_stop(const char *interface) -{ - char result_prop_name[PROPERTY_KEY_MAX]; - const char *ctrl_prop = "ctl.stop"; - const char *desired_status = "stopped"; - - snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result", - DHCP_PROP_NAME_PREFIX, - interface); - /* Stop the daemon and wait until it's reported to be stopped */ - property_set(ctrl_prop, DAEMON_NAME); - if (wait_for_property(DAEMON_PROP_NAME, desired_status, 5) < 0) { - return -1; - } - property_set(result_prop_name, "failed"); - return 0; -} - -/** - * Release the current DHCP client lease. - */ -int dhcp_release_lease(const char *interface) -{ - const char *ctrl_prop = "ctl.stop"; - const char *desired_status = "stopped"; - - /* Stop the daemon and wait until it's reported to be stopped */ - property_set(ctrl_prop, DAEMON_NAME); - if (wait_for_property(DAEMON_PROP_NAME, desired_status, 5) < 0) { - return -1; - } - return 0; -} - -char *dhcp_get_errmsg() { - return errmsg; -} diff --git a/libnetutils/dhcpclient.c b/libnetutils/dhcpclient.c deleted file mode 100644 index 45e392a66a959e961663d5440bbee562559de762..0000000000000000000000000000000000000000 --- a/libnetutils/dhcpclient.c +++ /dev/null @@ -1,562 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -#include <time.h> -#include <sys/time.h> -#include <poll.h> - -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> - -#include <cutils/properties.h> -#define LOG_TAG "DHCP" -#include <cutils/log.h> - -#include <dirent.h> - -#include "dhcpmsg.h" -#include "ifc_utils.h" -#include "packet.h" - -#define VERBOSE 2 - -static int verbose = 1; -static char errmsg[2048]; - -typedef unsigned long long msecs_t; -#if VERBOSE -void dump_dhcp_msg(); -#endif - -msecs_t get_msecs(void) -{ - struct timespec ts; - - if (clock_gettime(CLOCK_MONOTONIC, &ts)) { - return 0; - } else { - return (((msecs_t) ts.tv_sec) * ((msecs_t) 1000)) + - (((msecs_t) ts.tv_nsec) / ((msecs_t) 1000000)); - } -} - -void printerr(char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - vsnprintf(errmsg, sizeof(errmsg), fmt, ap); - va_end(ap); - - LOGD(errmsg); -} - -const char *dhcp_lasterror() -{ - return errmsg; -} - -int fatal(const char *reason) -{ - printerr("%s: %s\n", reason, strerror(errno)); - return -1; -// exit(1); -} - -const char *ipaddr(uint32_t addr) -{ - static char buf[32]; - - sprintf(buf,"%d.%d.%d.%d", - addr & 255, - ((addr >> 8) & 255), - ((addr >> 16) & 255), - (addr >> 24)); - return buf; -} - -typedef struct dhcp_info dhcp_info; - -struct dhcp_info { - uint32_t type; - - uint32_t ipaddr; - uint32_t gateway; - uint32_t netmask; - - uint32_t dns1; - uint32_t dns2; - - uint32_t serveraddr; - uint32_t lease; -}; - -dhcp_info last_good_info; - -void get_dhcp_info(uint32_t *ipaddr, uint32_t *gateway, uint32_t *mask, - uint32_t *dns1, uint32_t *dns2, uint32_t *server, - uint32_t *lease) -{ - *ipaddr = last_good_info.ipaddr; - *gateway = last_good_info.gateway; - *mask = last_good_info.netmask; - *dns1 = last_good_info.dns1; - *dns2 = last_good_info.dns2; - *server = last_good_info.serveraddr; - *lease = last_good_info.lease; -} - -static int ifc_configure(const char *ifname, dhcp_info *info) -{ - char dns_prop_name[PROPERTY_KEY_MAX]; - - if (ifc_set_addr(ifname, info->ipaddr)) { - printerr("failed to set ipaddr %s: %s\n", ipaddr(info->ipaddr), strerror(errno)); - return -1; - } - if (ifc_set_mask(ifname, info->netmask)) { - printerr("failed to set netmask %s: %s\n", ipaddr(info->netmask), strerror(errno)); - return -1; - } - if (ifc_create_default_route(ifname, info->gateway)) { - printerr("failed to set default route %s: %s\n", ipaddr(info->gateway), strerror(errno)); - return -1; - } - - snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", ifname); - property_set(dns_prop_name, info->dns1 ? ipaddr(info->dns1) : ""); - snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", ifname); - property_set(dns_prop_name, info->dns2 ? ipaddr(info->dns2) : ""); - - last_good_info = *info; - - return 0; -} - -static const char *dhcp_type_to_name(uint32_t type) -{ - switch(type) { - case DHCPDISCOVER: return "discover"; - case DHCPOFFER: return "offer"; - case DHCPREQUEST: return "request"; - case DHCPDECLINE: return "decline"; - case DHCPACK: return "ack"; - case DHCPNAK: return "nak"; - case DHCPRELEASE: return "release"; - case DHCPINFORM: return "inform"; - default: return "???"; - } -} - -void dump_dhcp_info(dhcp_info *info) -{ - char addr[20], gway[20], mask[20]; - LOGD("--- dhcp %s (%d) ---", - dhcp_type_to_name(info->type), info->type); - strcpy(addr, ipaddr(info->ipaddr)); - strcpy(gway, ipaddr(info->gateway)); - strcpy(mask, ipaddr(info->netmask)); - LOGD("ip %s gw %s mask %s", addr, gway, mask); - if (info->dns1) LOGD("dns1: %s", ipaddr(info->dns1)); - if (info->dns2) LOGD("dns2: %s", ipaddr(info->dns2)); - LOGD("server %s, lease %d seconds", - ipaddr(info->serveraddr), info->lease); -} - - -int decode_dhcp_msg(dhcp_msg *msg, int len, dhcp_info *info) -{ - uint8_t *x; - unsigned int opt; - int optlen; - - memset(info, 0, sizeof(dhcp_info)); - if (len < (DHCP_MSG_FIXED_SIZE + 4)) return -1; - - len -= (DHCP_MSG_FIXED_SIZE + 4); - - if (msg->options[0] != OPT_COOKIE1) return -1; - if (msg->options[1] != OPT_COOKIE2) return -1; - if (msg->options[2] != OPT_COOKIE3) return -1; - if (msg->options[3] != OPT_COOKIE4) return -1; - - x = msg->options + 4; - - while (len > 2) { - opt = *x++; - if (opt == OPT_PAD) { - len--; - continue; - } - if (opt == OPT_END) { - break; - } - optlen = *x++; - len -= 2; - if (optlen > len) { - break; - } - switch(opt) { - case OPT_SUBNET_MASK: - if (optlen >= 4) memcpy(&info->netmask, x, 4); - break; - case OPT_GATEWAY: - if (optlen >= 4) memcpy(&info->gateway, x, 4); - break; - case OPT_DNS: - if (optlen >= 4) memcpy(&info->dns1, x + 0, 4); - if (optlen >= 8) memcpy(&info->dns2, x + 4, 4); - break; - case OPT_LEASE_TIME: - if (optlen >= 4) { - memcpy(&info->lease, x, 4); - info->lease = ntohl(info->lease); - } - break; - case OPT_SERVER_ID: - if (optlen >= 4) memcpy(&info->serveraddr, x, 4); - break; - case OPT_MESSAGE_TYPE: - info->type = *x; - break; - default: - break; - } - x += optlen; - len -= optlen; - } - - info->ipaddr = msg->yiaddr; - - return 0; -} - -#if VERBOSE - -static void hex2str(char *buf, const unsigned char *array, int len) -{ - int i; - char *cp = buf; - - for (i = 0; i < len; i++) { - cp += sprintf(cp, " %02x ", array[i]); - } -} - -void dump_dhcp_msg(dhcp_msg *msg, int len) -{ - unsigned char *x; - unsigned int n,c; - int optsz; - const char *name; - char buf[2048]; - - LOGD("===== DHCP message:"); - if (len < DHCP_MSG_FIXED_SIZE) { - LOGD("Invalid length %d, should be %d", len, DHCP_MSG_FIXED_SIZE); - return; - } - - len -= DHCP_MSG_FIXED_SIZE; - - if (msg->op == OP_BOOTREQUEST) - name = "BOOTREQUEST"; - else if (msg->op == OP_BOOTREPLY) - name = "BOOTREPLY"; - else - name = "????"; - LOGD("op = %s (%d), htype = %d, hlen = %d, hops = %d", - name, msg->op, msg->htype, msg->hlen, msg->hops); - LOGD("xid = 0x%08x secs = %d, flags = 0x%04x optlen = %d", - ntohl(msg->xid), ntohs(msg->secs), ntohs(msg->flags), len); - LOGD("ciaddr = %s", ipaddr(msg->ciaddr)); - LOGD("yiaddr = %s", ipaddr(msg->yiaddr)); - LOGD("siaddr = %s", ipaddr(msg->siaddr)); - LOGD("giaddr = %s", ipaddr(msg->giaddr)); - - c = msg->hlen > 16 ? 16 : msg->hlen; - hex2str(buf, msg->chaddr, c); - LOGD("chaddr = {%s}", buf); - - for (n = 0; n < 64; n++) { - if ((msg->sname[n] < ' ') || (msg->sname[n] > 127)) { - if (msg->sname[n] == 0) break; - msg->sname[n] = '.'; - } - } - msg->sname[63] = 0; - - for (n = 0; n < 128; n++) { - if ((msg->file[n] < ' ') || (msg->file[n] > 127)) { - if (msg->file[n] == 0) break; - msg->file[n] = '.'; - } - } - msg->file[127] = 0; - - LOGD("sname = '%s'", msg->sname); - LOGD("file = '%s'", msg->file); - - if (len < 4) return; - len -= 4; - x = msg->options + 4; - - while (len > 2) { - if (*x == 0) { - x++; - len--; - continue; - } - if (*x == OPT_END) { - break; - } - len -= 2; - optsz = x[1]; - if (optsz > len) break; - if (x[0] == OPT_DOMAIN_NAME || x[0] == OPT_MESSAGE) { - if ((unsigned int)optsz < sizeof(buf) - 1) { - n = optsz; - } else { - n = sizeof(buf) - 1; - } - memcpy(buf, &x[2], n); - buf[n] = '\0'; - } else { - hex2str(buf, &x[2], optsz); - } - if (x[0] == OPT_MESSAGE_TYPE) - name = dhcp_type_to_name(x[2]); - else - name = NULL; - LOGD("op %d len %d {%s} %s", x[0], optsz, buf, name == NULL ? "" : name); - len -= optsz; - x = x + optsz + 2; - } -} - -#endif - -static int send_message(int sock, int if_index, dhcp_msg *msg, int size) -{ -#if VERBOSE > 1 - dump_dhcp_msg(msg, size); -#endif - return send_packet(sock, if_index, msg, size, INADDR_ANY, INADDR_BROADCAST, - PORT_BOOTP_CLIENT, PORT_BOOTP_SERVER); -} - -static int is_valid_reply(dhcp_msg *msg, dhcp_msg *reply, int sz) -{ - if (sz < DHCP_MSG_FIXED_SIZE) { - if (verbose) LOGD("netcfg: Wrong size %d != %d\n", sz, DHCP_MSG_FIXED_SIZE); - return 0; - } - if (reply->op != OP_BOOTREPLY) { - if (verbose) LOGD("netcfg: Wrong Op %d != %d\n", reply->op, OP_BOOTREPLY); - return 0; - } - if (reply->xid != msg->xid) { - if (verbose) LOGD("netcfg: Wrong Xid 0x%x != 0x%x\n", ntohl(reply->xid), - ntohl(msg->xid)); - return 0; - } - if (reply->htype != msg->htype) { - if (verbose) LOGD("netcfg: Wrong Htype %d != %d\n", reply->htype, msg->htype); - return 0; - } - if (reply->hlen != msg->hlen) { - if (verbose) LOGD("netcfg: Wrong Hlen %d != %d\n", reply->hlen, msg->hlen); - return 0; - } - if (memcmp(msg->chaddr, reply->chaddr, msg->hlen)) { - if (verbose) LOGD("netcfg: Wrong chaddr %x != %x\n", *(reply->chaddr),*(msg->chaddr)); - return 0; - } - return 1; -} - -#define STATE_SELECTING 1 -#define STATE_REQUESTING 2 - -#define TIMEOUT_INITIAL 4000 -#define TIMEOUT_MAX 32000 - -int dhcp_init_ifc(const char *ifname) -{ - dhcp_msg discover_msg; - dhcp_msg request_msg; - dhcp_msg reply; - dhcp_msg *msg; - dhcp_info info; - int s, r, size; - int valid_reply; - uint32_t xid; - unsigned char hwaddr[6]; - struct pollfd pfd; - unsigned int state; - unsigned int timeout; - int if_index; - - xid = (uint32_t) get_msecs(); - - if (ifc_get_hwaddr(ifname, hwaddr)) { - return fatal("cannot obtain interface address"); - } - if (ifc_get_ifindex(ifname, &if_index)) { - return fatal("cannot obtain interface index"); - } - - s = open_raw_socket(ifname, hwaddr, if_index); - - timeout = TIMEOUT_INITIAL; - state = STATE_SELECTING; - info.type = 0; - goto transmit; - - for (;;) { - pfd.fd = s; - pfd.events = POLLIN; - pfd.revents = 0; - r = poll(&pfd, 1, timeout); - - if (r == 0) { -#if VERBOSE - printerr("TIMEOUT\n"); -#endif - if (timeout >= TIMEOUT_MAX) { - printerr("timed out\n"); - if ( info.type == DHCPOFFER ) { - printerr("no acknowledgement from DHCP server\nconfiguring %s with offered parameters\n", ifname); - return ifc_configure(ifname, &info); - } - errno = ETIME; - close(s); - return -1; - } - timeout = timeout * 2; - - transmit: - size = 0; - msg = NULL; - switch(state) { - case STATE_SELECTING: - msg = &discover_msg; - size = init_dhcp_discover_msg(msg, hwaddr, xid); - break; - case STATE_REQUESTING: - msg = &request_msg; - size = init_dhcp_request_msg(msg, hwaddr, xid, info.ipaddr, info.serveraddr); - break; - default: - r = 0; - } - if (size != 0) { - r = send_message(s, if_index, msg, size); - if (r < 0) { - printerr("error sending dhcp msg: %s\n", strerror(errno)); - } - } - continue; - } - - if (r < 0) { - if ((errno == EAGAIN) || (errno == EINTR)) { - continue; - } - return fatal("poll failed"); - } - - errno = 0; - r = receive_packet(s, &reply); - if (r < 0) { - if (errno != 0) { - LOGD("receive_packet failed (%d): %s", r, strerror(errno)); - if (errno == ENETDOWN || errno == ENXIO) { - return -1; - } - } - continue; - } - -#if VERBOSE > 1 - dump_dhcp_msg(&reply, r); -#endif - decode_dhcp_msg(&reply, r, &info); - - if (state == STATE_SELECTING) { - valid_reply = is_valid_reply(&discover_msg, &reply, r); - } else { - valid_reply = is_valid_reply(&request_msg, &reply, r); - } - if (!valid_reply) { - printerr("invalid reply\n"); - continue; - } - - if (verbose) dump_dhcp_info(&info); - - switch(state) { - case STATE_SELECTING: - if (info.type == DHCPOFFER) { - state = STATE_REQUESTING; - timeout = TIMEOUT_INITIAL; - xid++; - goto transmit; - } - break; - case STATE_REQUESTING: - if (info.type == DHCPACK) { - printerr("configuring %s\n", ifname); - close(s); - return ifc_configure(ifname, &info); - } else if (info.type == DHCPNAK) { - printerr("configuration request denied\n"); - close(s); - return -1; - } else { - printerr("ignoring %s message in state %d\n", - dhcp_type_to_name(info.type), state); - } - break; - } - } - close(s); - return 0; -} - -int do_dhcp(char *iname) -{ - if (ifc_set_addr(iname, 0)) { - printerr("failed to set ip addr for %s to 0.0.0.0: %s\n", iname, strerror(errno)); - return -1; - } - - if (ifc_up(iname)) { - printerr("failed to bring up interface %s: %s\n", iname, strerror(errno)); - return -1; - } - - return dhcp_init_ifc(iname); -} diff --git a/libnetutils/dhcpmsg.c b/libnetutils/dhcpmsg.c deleted file mode 100644 index 1e0a233fc3010871f421789c36306abdbd96be8e..0000000000000000000000000000000000000000 --- a/libnetutils/dhcpmsg.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> -#include <netinet/in.h> - -#include "dhcpmsg.h" - -static void *init_dhcp_msg(dhcp_msg *msg, int type, void *hwaddr, uint32_t xid) -{ - uint8_t *x; - - memset(msg, 0, sizeof(dhcp_msg)); - - msg->op = OP_BOOTREQUEST; - msg->htype = HTYPE_ETHER; - msg->hlen = 6; - msg->hops = 0; - - msg->flags = htons(FLAGS_BROADCAST); - - msg->xid = xid; - - memcpy(msg->chaddr, hwaddr, 6); - - x = msg->options; - - *x++ = OPT_COOKIE1; - *x++ = OPT_COOKIE2; - *x++ = OPT_COOKIE3; - *x++ = OPT_COOKIE4; - - *x++ = OPT_MESSAGE_TYPE; - *x++ = 1; - *x++ = type; - - return x; -} - -int init_dhcp_discover_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid) -{ - uint8_t *x; - - x = init_dhcp_msg(msg, DHCPDISCOVER, hwaddr, xid); - - *x++ = OPT_PARAMETER_LIST; - *x++ = 4; - *x++ = OPT_SUBNET_MASK; - *x++ = OPT_GATEWAY; - *x++ = OPT_DNS; - *x++ = OPT_BROADCAST_ADDR; - - *x++ = OPT_END; - - return DHCP_MSG_FIXED_SIZE + (x - msg->options); -} - -int init_dhcp_request_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid, - uint32_t ipaddr, uint32_t serveraddr) -{ - uint8_t *x; - - x = init_dhcp_msg(msg, DHCPREQUEST, hwaddr, xid); - - *x++ = OPT_PARAMETER_LIST; - *x++ = 4; - *x++ = OPT_SUBNET_MASK; - *x++ = OPT_GATEWAY; - *x++ = OPT_DNS; - *x++ = OPT_BROADCAST_ADDR; - - *x++ = OPT_REQUESTED_IP; - *x++ = 4; - memcpy(x, &ipaddr, 4); - x += 4; - - *x++ = OPT_SERVER_ID; - *x++ = 4; - memcpy(x, &serveraddr, 4); - x += 4; - - *x++ = OPT_END; - - return DHCP_MSG_FIXED_SIZE + (x - msg->options); -} diff --git a/libnetutils/dhcpmsg.h b/libnetutils/dhcpmsg.h deleted file mode 100644 index c86e400d461cd0887ce742e1aee5794f3962c5e8..0000000000000000000000000000000000000000 --- a/libnetutils/dhcpmsg.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _WIFI_DHCP_H_ -#define _WIFI_DHCP_H_ - -#include <sys/types.h> - -#define PORT_BOOTP_SERVER 67 -#define PORT_BOOTP_CLIENT 68 - -/* RFC 2131 p 9 */ -typedef struct dhcp_msg dhcp_msg; - -#define OP_BOOTREQUEST 1 -#define OP_BOOTREPLY 2 - -#define FLAGS_BROADCAST 0x8000 - -#define HTYPE_ETHER 1 - -struct dhcp_msg -{ - uint8_t op; /* BOOTREQUEST / BOOTREPLY */ - uint8_t htype; /* hw addr type */ - uint8_t hlen; /* hw addr len */ - uint8_t hops; /* client set to 0 */ - - uint32_t xid; /* transaction id */ - - uint16_t secs; /* seconds since start of acq */ - uint16_t flags; - - uint32_t ciaddr; /* client IP addr */ - uint32_t yiaddr; /* your (client) IP addr */ - uint32_t siaddr; /* ip addr of next server */ - /* (DHCPOFFER and DHCPACK) */ - uint32_t giaddr; /* relay agent IP addr */ - - uint8_t chaddr[16]; /* client hw addr */ - char sname[64]; /* asciiz server hostname */ - char file[128]; /* asciiz boot file name */ - - uint8_t options[1024]; /* optional parameters */ -}; - -#define DHCP_MSG_FIXED_SIZE 236 - -/* first four bytes of options are a cookie to indicate that -** the payload are DHCP options as opposed to some other BOOTP -** extension. -*/ -#define OPT_COOKIE1 0x63 -#define OPT_COOKIE2 0x82 -#define OPT_COOKIE3 0x53 -#define OPT_COOKIE4 0x63 - -/* BOOTP/DHCP options - see RFC 2132 */ -#define OPT_PAD 0 - -#define OPT_SUBNET_MASK 1 /* 4 <ipaddr> */ -#define OPT_TIME_OFFSET 2 /* 4 <seconds> */ -#define OPT_GATEWAY 3 /* 4*n <ipaddr> * n */ -#define OPT_DNS 6 /* 4*n <ipaddr> * n */ -#define OPT_DOMAIN_NAME 15 /* n <domainnamestring> */ -#define OPT_BROADCAST_ADDR 28 /* 4 <ipaddr> */ - -#define OPT_REQUESTED_IP 50 /* 4 <ipaddr> */ -#define OPT_LEASE_TIME 51 /* 4 <seconds> */ -#define OPT_MESSAGE_TYPE 53 /* 1 <msgtype> */ -#define OPT_SERVER_ID 54 /* 4 <ipaddr> */ -#define OPT_PARAMETER_LIST 55 /* n <optcode> * n */ -#define OPT_MESSAGE 56 /* n <errorstring> */ -#define OPT_CLASS_ID 60 /* n <opaque> */ -#define OPT_CLIENT_ID 61 /* n <opaque> */ -#define OPT_END 255 - -/* DHCP message types */ -#define DHCPDISCOVER 1 -#define DHCPOFFER 2 -#define DHCPREQUEST 3 -#define DHCPDECLINE 4 -#define DHCPACK 5 -#define DHCPNAK 6 -#define DHCPRELEASE 7 -#define DHCPINFORM 8 - -int init_dhcp_discover_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid); - -int init_dhcp_request_msg(dhcp_msg *msg, void *hwaddr, uint32_t xid, - uint32_t ipaddr, uint32_t serveraddr); - -#endif diff --git a/libnetutils/ifc_utils.c b/libnetutils/ifc_utils.c deleted file mode 100644 index 88635d96943e979d863d4ab9cdf9423e9c8fb359..0000000000000000000000000000000000000000 --- a/libnetutils/ifc_utils.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/types.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -#include <linux/if.h> -#include <linux/sockios.h> -#include <linux/route.h> -#include <linux/wireless.h> - -#ifdef ANDROID -#define LOG_TAG "NetUtils" -#include <cutils/log.h> -#include <cutils/properties.h> -#else -#include <stdio.h> -#include <string.h> -#define LOGD printf -#define LOGW printf -#endif - -static int ifc_ctl_sock = -1; -void printerr(char *fmt, ...); - -static const char *ipaddr_to_string(uint32_t addr) -{ - struct in_addr in_addr; - - in_addr.s_addr = addr; - return inet_ntoa(in_addr); -} - -int ifc_init(void) -{ - if (ifc_ctl_sock == -1) { - ifc_ctl_sock = socket(AF_INET, SOCK_DGRAM, 0); - if (ifc_ctl_sock < 0) { - printerr("socket() failed: %s\n", strerror(errno)); - } - } - return ifc_ctl_sock < 0 ? -1 : 0; -} - -void ifc_close(void) -{ - if (ifc_ctl_sock != -1) { - (void)close(ifc_ctl_sock); - ifc_ctl_sock = -1; - } -} - -static void ifc_init_ifr(const char *name, struct ifreq *ifr) -{ - memset(ifr, 0, sizeof(struct ifreq)); - strncpy(ifr->ifr_name, name, IFNAMSIZ); - ifr->ifr_name[IFNAMSIZ - 1] = 0; -} - -int ifc_get_hwaddr(const char *name, void *ptr) -{ - int r; - struct ifreq ifr; - ifc_init_ifr(name, &ifr); - - r = ioctl(ifc_ctl_sock, SIOCGIFHWADDR, &ifr); - if(r < 0) return -1; - - memcpy(ptr, &ifr.ifr_hwaddr.sa_data, 6); - return 0; -} - -int ifc_get_ifindex(const char *name, int *if_indexp) -{ - int r; - struct ifreq ifr; - ifc_init_ifr(name, &ifr); - - r = ioctl(ifc_ctl_sock, SIOCGIFINDEX, &ifr); - if(r < 0) return -1; - - *if_indexp = ifr.ifr_ifindex; - return 0; -} - -static int ifc_set_flags(const char *name, unsigned set, unsigned clr) -{ - struct ifreq ifr; - ifc_init_ifr(name, &ifr); - - if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) return -1; - ifr.ifr_flags = (ifr.ifr_flags & (~clr)) | set; - return ioctl(ifc_ctl_sock, SIOCSIFFLAGS, &ifr); -} - -int ifc_up(const char *name) -{ - return ifc_set_flags(name, IFF_UP, 0); -} - -int ifc_down(const char *name) -{ - return ifc_set_flags(name, 0, IFF_UP); -} - -static void init_sockaddr_in(struct sockaddr *sa, in_addr_t addr) -{ - struct sockaddr_in *sin = (struct sockaddr_in *) sa; - sin->sin_family = AF_INET; - sin->sin_port = 0; - sin->sin_addr.s_addr = addr; -} - -int ifc_set_addr(const char *name, in_addr_t addr) -{ - struct ifreq ifr; - - ifc_init_ifr(name, &ifr); - init_sockaddr_in(&ifr.ifr_addr, addr); - - return ioctl(ifc_ctl_sock, SIOCSIFADDR, &ifr); -} - -int ifc_set_mask(const char *name, in_addr_t mask) -{ - struct ifreq ifr; - - ifc_init_ifr(name, &ifr); - init_sockaddr_in(&ifr.ifr_addr, mask); - - return ioctl(ifc_ctl_sock, SIOCSIFNETMASK, &ifr); -} - -int ifc_get_info(const char *name, in_addr_t *addr, in_addr_t *mask, unsigned *flags) -{ - struct ifreq ifr; - ifc_init_ifr(name, &ifr); - - if (addr != NULL) { - if(ioctl(ifc_ctl_sock, SIOCGIFADDR, &ifr) < 0) { - *addr = 0; - } else { - *addr = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; - } - } - - if (mask != NULL) { - if(ioctl(ifc_ctl_sock, SIOCGIFNETMASK, &ifr) < 0) { - *mask = 0; - } else { - *mask = ((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr; - } - } - - if (flags != NULL) { - if(ioctl(ifc_ctl_sock, SIOCGIFFLAGS, &ifr) < 0) { - *flags = 0; - } else { - *flags = ifr.ifr_flags; - } - } - - return 0; -} - - -int ifc_create_default_route(const char *name, in_addr_t addr) -{ - struct rtentry rt; - - memset(&rt, 0, sizeof(rt)); - - rt.rt_dst.sa_family = AF_INET; - rt.rt_flags = RTF_UP | RTF_GATEWAY; - rt.rt_dev = (void*) name; - init_sockaddr_in(&rt.rt_genmask, 0); - init_sockaddr_in(&rt.rt_gateway, addr); - - return ioctl(ifc_ctl_sock, SIOCADDRT, &rt); -} - -int ifc_add_host_route(const char *name, in_addr_t addr) -{ - struct rtentry rt; - int result; - - memset(&rt, 0, sizeof(rt)); - - rt.rt_dst.sa_family = AF_INET; - rt.rt_flags = RTF_UP | RTF_HOST; - rt.rt_dev = (void*) name; - init_sockaddr_in(&rt.rt_dst, addr); - init_sockaddr_in(&rt.rt_genmask, 0); - init_sockaddr_in(&rt.rt_gateway, 0); - - ifc_init(); - result = ioctl(ifc_ctl_sock, SIOCADDRT, &rt); - if (result < 0 && errno == EEXIST) { - result = 0; - } - ifc_close(); - return result; -} - -int ifc_disable(const char *ifname) -{ - int result; - - ifc_init(); - result = ifc_down(ifname); - ifc_set_addr(ifname, 0); - ifc_close(); - return result; -} - -int ifc_reset_connections(const char *ifname) -{ -#ifdef HAVE_ANDROID_OS - int result; - in_addr_t myaddr; - struct ifreq ifr; - - ifc_init(); - ifc_get_info(ifname, &myaddr, NULL, NULL); - ifc_init_ifr(ifname, &ifr); - init_sockaddr_in(&ifr.ifr_addr, myaddr); - result = ioctl(ifc_ctl_sock, SIOCKILLADDR, &ifr); - ifc_close(); - - return result; -#else - return 0; -#endif -} - -/* - * Remove the routes associated with the named interface. - */ -int ifc_remove_host_routes(const char *name) -{ - char ifname[64]; - in_addr_t dest, gway, mask; - int flags, refcnt, use, metric, mtu, win, irtt; - struct rtentry rt; - FILE *fp; - struct in_addr addr; - - fp = fopen("/proc/net/route", "r"); - if (fp == NULL) - return -1; - /* Skip the header line */ - if (fscanf(fp, "%*[^\n]\n") < 0) { - fclose(fp); - return -1; - } - ifc_init(); - for (;;) { - int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", - ifname, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, - &mtu, &win, &irtt); - if (nread != 11) { - break; - } - if ((flags & (RTF_UP|RTF_HOST)) != (RTF_UP|RTF_HOST) - || strcmp(ifname, name) != 0) { - continue; - } - memset(&rt, 0, sizeof(rt)); - rt.rt_dev = (void *)name; - init_sockaddr_in(&rt.rt_dst, dest); - init_sockaddr_in(&rt.rt_gateway, gway); - init_sockaddr_in(&rt.rt_genmask, mask); - addr.s_addr = dest; - if (ioctl(ifc_ctl_sock, SIOCDELRT, &rt) < 0) { - LOGD("failed to remove route for %s to %s: %s", - ifname, inet_ntoa(addr), strerror(errno)); - } - } - fclose(fp); - ifc_close(); - return 0; -} - -/* - * Return the address of the default gateway - * - * TODO: factor out common code from this and remove_host_routes() - * so that we only scan /proc/net/route in one place. - */ -int ifc_get_default_route(const char *ifname) -{ - char name[64]; - in_addr_t dest, gway, mask; - int flags, refcnt, use, metric, mtu, win, irtt; - int result; - FILE *fp; - - fp = fopen("/proc/net/route", "r"); - if (fp == NULL) - return 0; - /* Skip the header line */ - if (fscanf(fp, "%*[^\n]\n") < 0) { - fclose(fp); - return 0; - } - ifc_init(); - result = 0; - for (;;) { - int nread = fscanf(fp, "%63s%X%X%X%d%d%d%X%d%d%d\n", - name, &dest, &gway, &flags, &refcnt, &use, &metric, &mask, - &mtu, &win, &irtt); - if (nread != 11) { - break; - } - if ((flags & (RTF_UP|RTF_GATEWAY)) == (RTF_UP|RTF_GATEWAY) - && dest == 0 - && strcmp(ifname, name) == 0) { - result = gway; - break; - } - } - fclose(fp); - ifc_close(); - return result; -} - -/* - * Sets the specified gateway as the default route for the named interface. - */ -int ifc_set_default_route(const char *ifname, in_addr_t gateway) -{ - struct in_addr addr; - int result; - - ifc_init(); - addr.s_addr = gateway; - if ((result = ifc_create_default_route(ifname, gateway)) < 0) { - LOGD("failed to add %s as default route for %s: %s", - inet_ntoa(addr), ifname, strerror(errno)); - } - ifc_close(); - return result; -} - -/* - * Removes the default route for the named interface. - */ -int ifc_remove_default_route(const char *ifname) -{ - struct rtentry rt; - int result; - - ifc_init(); - memset(&rt, 0, sizeof(rt)); - rt.rt_dev = (void *)ifname; - rt.rt_flags = RTF_UP|RTF_GATEWAY; - init_sockaddr_in(&rt.rt_dst, 0); - if ((result = ioctl(ifc_ctl_sock, SIOCDELRT, &rt)) < 0) { - LOGD("failed to remove default route for %s: %s", ifname, strerror(errno)); - } - ifc_close(); - return result; -} - -int -ifc_configure(const char *ifname, - in_addr_t address, - in_addr_t netmask, - in_addr_t gateway, - in_addr_t dns1, - in_addr_t dns2) { - - char dns_prop_name[PROPERTY_KEY_MAX]; - - ifc_init(); - - if (ifc_up(ifname)) { - printerr("failed to turn on interface %s: %s\n", ifname, strerror(errno)); - ifc_close(); - return -1; - } - if (ifc_set_addr(ifname, address)) { - printerr("failed to set ipaddr %s: %s\n", ipaddr_to_string(address), strerror(errno)); - ifc_close(); - return -1; - } - if (ifc_set_mask(ifname, netmask)) { - printerr("failed to set netmask %s: %s\n", ipaddr_to_string(netmask), strerror(errno)); - ifc_close(); - return -1; - } - if (ifc_create_default_route(ifname, gateway)) { - printerr("failed to set default route %s: %s\n", ipaddr_to_string(gateway), strerror(errno)); - ifc_close(); - return -1; - } - - ifc_close(); - - snprintf(dns_prop_name, sizeof(dns_prop_name), "dhcp.%s.dns1", ifname); - property_set(dns_prop_name, dns1 ? ipaddr_to_string(dns1) : ""); - snprintf(dns_prop_name, sizeof(dns_prop_name), "dhcp.%s.dns2", ifname); - property_set(dns_prop_name, dns2 ? ipaddr_to_string(dns2) : ""); - - return 0; -} diff --git a/libnetutils/ifc_utils.h b/libnetutils/ifc_utils.h deleted file mode 100644 index 49b8747a31cc88b5e838470389642b1ff3c12cdd..0000000000000000000000000000000000000000 --- a/libnetutils/ifc_utils.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _IFC_UTILS_H_ -#define _IFC_UTILS_H_ - -int ifc_init(void); - -int ifc_get_ifindex(const char *name, int *if_indexp); -int ifc_get_hwaddr(const char *name, void *ptr); - -int ifc_up(const char *name); -int ifc_down(const char *name); - -int ifc_set_addr(const char *name, unsigned addr); -int ifc_set_mask(const char *name, unsigned mask); - -int ifc_create_default_route(const char *name, unsigned addr); - -int ifc_get_info(const char *name, unsigned *addr, unsigned *mask, unsigned *flags); - -#endif diff --git a/libnetutils/packet.c b/libnetutils/packet.c deleted file mode 100644 index 9388345c797210b933fd56543320891455d800b3..0000000000000000000000000000000000000000 --- a/libnetutils/packet.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <unistd.h> -#include <sys/uio.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#include <netinet/udp.h> -#include <linux/if_packet.h> -#include <linux/if_ether.h> -#include <errno.h> - -#ifdef ANDROID -#define LOG_TAG "DHCP" -#include <cutils/log.h> -#else -#include <stdio.h> -#include <string.h> -#define LOGD printf -#define LOGW printf -#endif - -#include "dhcpmsg.h" - -int fatal(); - -int open_raw_socket(const char *ifname, uint8_t *hwaddr, int if_index) -{ - int s, flag; - struct sockaddr_ll bindaddr; - - if((s = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP))) < 0) { - return fatal("socket(PF_PACKET)"); - } - - memset(&bindaddr, 0, sizeof(bindaddr)); - bindaddr.sll_family = AF_PACKET; - bindaddr.sll_protocol = htons(ETH_P_IP); - bindaddr.sll_halen = ETH_ALEN; - memcpy(bindaddr.sll_addr, hwaddr, ETH_ALEN); - bindaddr.sll_ifindex = if_index; - - if (bind(s, (struct sockaddr *)&bindaddr, sizeof(bindaddr)) < 0) { - return fatal("Cannot bind raw socket to interface"); - } - - return s; -} - -static uint32_t checksum(void *buffer, unsigned int count, uint32_t startsum) -{ - uint16_t *up = (uint16_t *)buffer; - uint32_t sum = startsum; - uint32_t upper16; - - while (count > 1) { - sum += *up++; - count -= 2; - } - if (count > 0) { - sum += (uint16_t) *(uint8_t *)up; - } - while ((upper16 = (sum >> 16)) != 0) { - sum = (sum & 0xffff) + upper16; - } - return sum; -} - -static uint32_t finish_sum(uint32_t sum) -{ - return ~sum & 0xffff; -} - -int send_packet(int s, int if_index, struct dhcp_msg *msg, int size, - uint32_t saddr, uint32_t daddr, uint32_t sport, uint32_t dport) -{ - struct iphdr ip; - struct udphdr udp; - struct iovec iov[3]; - uint32_t udpsum; - uint16_t temp; - struct msghdr msghdr; - struct sockaddr_ll destaddr; - - ip.version = IPVERSION; - ip.ihl = sizeof(ip) >> 2; - ip.tos = 0; - ip.tot_len = htons(sizeof(ip) + sizeof(udp) + size); - ip.id = 0; - ip.frag_off = 0; - ip.ttl = IPDEFTTL; - ip.protocol = IPPROTO_UDP; - ip.check = 0; - ip.saddr = saddr; - ip.daddr = daddr; - ip.check = finish_sum(checksum(&ip, sizeof(ip), 0)); - - udp.source = htons(sport); - udp.dest = htons(dport); - udp.len = htons(sizeof(udp) + size); - udp.check = 0; - - /* Calculate checksum for pseudo header */ - udpsum = checksum(&ip.saddr, sizeof(ip.saddr), 0); - udpsum = checksum(&ip.daddr, sizeof(ip.daddr), udpsum); - temp = htons(IPPROTO_UDP); - udpsum = checksum(&temp, sizeof(temp), udpsum); - temp = udp.len; - udpsum = checksum(&temp, sizeof(temp), udpsum); - - /* Add in the checksum for the udp header */ - udpsum = checksum(&udp, sizeof(udp), udpsum); - - /* Add in the checksum for the data */ - udpsum = checksum(msg, size, udpsum); - udp.check = finish_sum(udpsum); - - iov[0].iov_base = (char *)&ip; - iov[0].iov_len = sizeof(ip); - iov[1].iov_base = (char *)&udp; - iov[1].iov_len = sizeof(udp); - iov[2].iov_base = (char *)msg; - iov[2].iov_len = size; - memset(&destaddr, 0, sizeof(destaddr)); - destaddr.sll_family = AF_PACKET; - destaddr.sll_protocol = htons(ETH_P_IP); - destaddr.sll_ifindex = if_index; - destaddr.sll_halen = ETH_ALEN; - memcpy(destaddr.sll_addr, "\xff\xff\xff\xff\xff\xff", ETH_ALEN); - - msghdr.msg_name = &destaddr; - msghdr.msg_namelen = sizeof(destaddr); - msghdr.msg_iov = iov; - msghdr.msg_iovlen = sizeof(iov) / sizeof(struct iovec); - msghdr.msg_flags = 0; - msghdr.msg_control = 0; - msghdr.msg_controllen = 0; - return sendmsg(s, &msghdr, 0); -} - -int receive_packet(int s, struct dhcp_msg *msg) -{ - int nread; - int is_valid; - struct dhcp_packet { - struct iphdr ip; - struct udphdr udp; - struct dhcp_msg dhcp; - } packet; - int dhcp_size; - uint32_t sum; - uint16_t temp; - uint32_t saddr, daddr; - - nread = read(s, &packet, sizeof(packet)); - if (nread < 0) { - return -1; - } - /* - * The raw packet interface gives us all packets received by the - * network interface. We need to filter out all packets that are - * not meant for us. - */ - is_valid = 0; - if (nread < (int)(sizeof(struct iphdr) + sizeof(struct udphdr))) { -#if VERBOSE - LOGD("Packet is too small (%d) to be a UDP datagram", nread); -#endif - } else if (packet.ip.version != IPVERSION || packet.ip.ihl != (sizeof(packet.ip) >> 2)) { -#if VERBOSE - LOGD("Not a valid IP packet"); -#endif - } else if (nread < ntohs(packet.ip.tot_len)) { -#if VERBOSE - LOGD("Packet was truncated (read %d, needed %d)", nread, ntohs(packet.ip.tot_len)); -#endif - } else if (packet.ip.protocol != IPPROTO_UDP) { -#if VERBOSE - LOGD("IP protocol (%d) is not UDP", packet.ip.protocol); -#endif - } else if (packet.udp.dest != htons(PORT_BOOTP_CLIENT)) { -#if VERBOSE - LOGD("UDP dest port (%d) is not DHCP client", ntohs(packet.udp.dest)); -#endif - } else { - is_valid = 1; - } - - if (!is_valid) { - return -1; - } - - /* Seems like it's probably a valid DHCP packet */ - /* validate IP header checksum */ - sum = finish_sum(checksum(&packet.ip, sizeof(packet.ip), 0)); - if (sum != 0) { - LOGW("IP header checksum failure (0x%x)", packet.ip.check); - return -1; - } - /* - * Validate the UDP checksum. - * Since we don't need the IP header anymore, we "borrow" it - * to construct the pseudo header used in the checksum calculation. - */ - dhcp_size = ntohs(packet.udp.len) - sizeof(packet.udp); - saddr = packet.ip.saddr; - daddr = packet.ip.daddr; - nread = ntohs(packet.ip.tot_len); - memset(&packet.ip, 0, sizeof(packet.ip)); - packet.ip.saddr = saddr; - packet.ip.daddr = daddr; - packet.ip.protocol = IPPROTO_UDP; - packet.ip.tot_len = packet.udp.len; - temp = packet.udp.check; - packet.udp.check = 0; - sum = finish_sum(checksum(&packet, nread, 0)); - packet.udp.check = temp; - if (temp != sum) { - LOGW("UDP header checksum failure (0x%x should be 0x%x)", sum, temp); - return -1; - } - memcpy(msg, &packet.dhcp, dhcp_size); - return dhcp_size; -} diff --git a/libnetutils/packet.h b/libnetutils/packet.h deleted file mode 100644 index aade392df56981c55017c41db303fa0ef7488b6b..0000000000000000000000000000000000000000 --- a/libnetutils/packet.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2008, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _WIFI_PACKET_H_ -#define _WIFI_PACKET_H_ - -int open_raw_socket(const char *ifname, uint8_t *hwaddr, int if_index); -int send_packet(int s, int if_index, struct dhcp_msg *msg, int size, - uint32_t saddr, uint32_t daddr, uint32_t sport, uint32_t dport); -int receive_packet(int s, struct dhcp_msg *msg); - -#endif diff --git a/libpixelflinger/Android.mk b/libpixelflinger/Android.mk deleted file mode 100644 index 50eb5f5d58f614b8890a10110d8608d37c6d898a..0000000000000000000000000000000000000000 --- a/libpixelflinger/Android.mk +++ /dev/null @@ -1,92 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# -# ARMv6 specific objects -# - -ifeq ($(TARGET_ARCH),arm) -LOCAL_ASFLAGS := -march=armv6 -LOCAL_SRC_FILES := rotate90CW_4x4_16v6.S -LOCAL_MODULE := libpixelflinger_armv6 -include $(BUILD_STATIC_LIBRARY) -endif - -# -# C/C++ and ARMv5 objects -# - -include $(CLEAR_VARS) -PIXELFLINGER_SRC_FILES:= \ - codeflinger/ARMAssemblerInterface.cpp \ - codeflinger/ARMAssemblerProxy.cpp \ - codeflinger/ARMAssembler.cpp \ - codeflinger/CodeCache.cpp \ - codeflinger/GGLAssembler.cpp \ - codeflinger/load_store.cpp \ - codeflinger/blending.cpp \ - codeflinger/texturing.cpp \ - codeflinger/disassem.c \ - tinyutils/SharedBuffer.cpp \ - tinyutils/VectorImpl.cpp \ - fixed.cpp.arm \ - picker.cpp.arm \ - pixelflinger.cpp.arm \ - trap.cpp.arm \ - scanline.cpp.arm \ - format.cpp \ - clear.cpp \ - raster.cpp \ - buffer.cpp - -ifeq ($(TARGET_ARCH),arm) -PIXELFLINGER_SRC_FILES += t32cb16blend.S -endif - -ifeq ($(TARGET_ARCH),arm) -# special optimization flags for pixelflinger -PIXELFLINGER_CFLAGS += -fstrict-aliasing -fomit-frame-pointer -endif - -LOCAL_SHARED_LIBRARIES := libcutils - -ifneq ($(TARGET_ARCH),arm) -# Required to define logging functions on the simulator. -# TODO: move the simulator logging functions into libcutils with -# the rest of the basic log stuff. -LOCAL_SHARED_LIBRARIES += libutils -endif - -# -# Shared library -# - -LOCAL_MODULE:= libpixelflinger -LOCAL_SRC_FILES := $(PIXELFLINGER_SRC_FILES) -LOCAL_CFLAGS := $(PIXELFLINGER_CFLAGS) -ifneq ($(BUILD_TINY_ANDROID),true) -# Really this should go away entirely or at least not depend on -# libhardware, but this at least gets us built. -LOCAL_SHARED_LIBRARIES += libhardware_legacy -LOCAL_CFLAGS += -DWITH_LIB_HARDWARE -endif -ifeq ($(TARGET_ARCH),arm) -LOCAL_WHOLE_STATIC_LIBRARIES := libpixelflinger_armv6 -endif -include $(BUILD_SHARED_LIBRARY) - -# -# Static library version -# - -include $(CLEAR_VARS) -LOCAL_MODULE:= libpixelflinger_static -LOCAL_SRC_FILES := $(PIXELFLINGER_SRC_FILES) -LOCAL_CFLAGS := $(PIXELFLINGER_CFLAGS) -ifeq ($(TARGET_ARCH),arm) -LOCAL_WHOLE_STATIC_LIBRARIES := libpixelflinger_armv6 -endif -include $(BUILD_STATIC_LIBRARY) - - -include $(call all-makefiles-under,$(LOCAL_PATH)) diff --git a/libpixelflinger/MODULE_LICENSE_APACHE2 b/libpixelflinger/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libpixelflinger/NOTICE b/libpixelflinger/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/libpixelflinger/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/libpixelflinger/buffer.cpp b/libpixelflinger/buffer.cpp deleted file mode 100644 index af7356b9275634cd4ea8dda8755e86abb1fb2827..0000000000000000000000000000000000000000 --- a/libpixelflinger/buffer.cpp +++ /dev/null @@ -1,384 +0,0 @@ -/* libs/pixelflinger/buffer.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <assert.h> - -#include "buffer.h" - -namespace android { -// ---------------------------------------------------------------------------- - -static void read_pixel(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel); -static void write_pixel(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, const pixel_t* pixel); -static void readRGB565(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel); -static void readABGR8888(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel); - -static uint32_t logic_op(int op, uint32_t s, uint32_t d); -static uint32_t extract(uint32_t v, int h, int l, int bits); -static uint32_t expand(uint32_t v, int sbits, int dbits); -static uint32_t downshift_component(uint32_t in, uint32_t v, - int sh, int sl, int dh, int dl, int ch, int cl, int dither); - -// ---------------------------------------------------------------------------- - -void ggl_init_texture(context_t* c) -{ - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { - texture_t& t = c->state.texture[i]; - t.s_coord = GGL_ONE_TO_ONE; - t.t_coord = GGL_ONE_TO_ONE; - t.s_wrap = GGL_REPEAT; - t.t_wrap = GGL_REPEAT; - t.min_filter = GGL_NEAREST; - t.mag_filter = GGL_NEAREST; - t.env = GGL_MODULATE; - } - c->activeTMU = &(c->state.texture[0]); -} - -void ggl_set_surface(context_t* c, surface_t* dst, const GGLSurface* src) -{ - dst->width = src->width; - dst->height = src->height; - dst->stride = src->stride; - dst->data = src->data; - dst->format = src->format; - dst->dirty = 1; - if (__builtin_expect(dst->stride < 0, false)) { - const GGLFormat& pixelFormat(c->formats[dst->format]); - const int32_t bpr = -dst->stride * pixelFormat.size; - dst->data += bpr * (dst->height-1); - } -} - -static void pick_read_write(surface_t* s) -{ - // Choose best reader/writers. - switch (s->format) { - case GGL_PIXEL_FORMAT_RGBA_8888: s->read = readABGR8888; break; - case GGL_PIXEL_FORMAT_RGB_565: s->read = readRGB565; break; - default: s->read = read_pixel; break; - } - s->write = write_pixel; -} - -void ggl_pick_texture(context_t* c) -{ - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - surface_t& s = c->state.texture[i].surface; - if ((!c->state.texture[i].enable) || (!s.dirty)) - continue; - s.dirty = 0; - pick_read_write(&s); - generated_tex_vars_t& gen = c->generated_vars.texture[i]; - gen.width = s.width; - gen.height = s.height; - gen.stride = s.stride; - gen.data = int32_t(s.data); - } -} - -void ggl_pick_cb(context_t* c) -{ - surface_t& s = c->state.buffers.color; - if (s.dirty) { - s.dirty = 0; - pick_read_write(&s); - } -} - -// ---------------------------------------------------------------------------- - -void read_pixel(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel) -{ - assert((x < s->width) && (y < s->height)); - - const GGLFormat* f = &(c->formats[s->format]); - int32_t index = x + (s->stride * y); - uint8_t* const data = s->data + index * f->size; - uint32_t v = 0; - switch (f->size) { - case 1: v = *data; break; - case 2: v = *(uint16_t*)data; break; - case 3: v = (data[2]<<16)|(data[1]<<8)|data[0]; break; - case 4: v = GGL_RGBA_TO_HOST(*(uint32_t*)data); break; - } - for (int i=0 ; i<4 ; i++) { - pixel->s[i] = f->c[i].h - f->c[i].l; - if (pixel->s[i]) - pixel->c[i] = extract(v, f->c[i].h, f->c[i].l, f->size*8); - } -} - -void readRGB565(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel) -{ - uint16_t v = *(reinterpret_cast<uint16_t*>(s->data) + (x + (s->stride * y))); - pixel->c[0] = 0; - pixel->c[1] = v>>11; - pixel->c[2] = (v>>5)&0x3F; - pixel->c[3] = v&0x1F; - pixel->s[0] = 0; - pixel->s[1] = 5; - pixel->s[2] = 6; - pixel->s[3] = 5; -} - -void readABGR8888(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, pixel_t* pixel) -{ - uint32_t v = *(reinterpret_cast<uint32_t*>(s->data) + (x + (s->stride * y))); - v = GGL_RGBA_TO_HOST(v); - pixel->c[0] = v>>24; // A - pixel->c[1] = v&0xFF; // R - pixel->c[2] = (v>>8)&0xFF; // G - pixel->c[3] = (v>>16)&0xFF; // B - pixel->s[0] = - pixel->s[1] = - pixel->s[2] = - pixel->s[3] = 8; -} - -void write_pixel(const surface_t* s, context_t* c, - uint32_t x, uint32_t y, const pixel_t* pixel) -{ - assert((x < s->width) && (y < s->height)); - - int dither = -1; - if (c->state.enables & GGL_ENABLE_DITHER) { - dither = c->ditherMatrix[ (x & GGL_DITHER_MASK) + - ((y & GGL_DITHER_MASK)<<GGL_DITHER_ORDER_SHIFT) ]; - } - - const GGLFormat* f = &(c->formats[s->format]); - int32_t index = x + (s->stride * y); - uint8_t* const data = s->data + index * f->size; - - uint32_t mask = 0; - uint32_t v = 0; - for (int i=0 ; i<4 ; i++) { - const int component_mask = 1 << i; - if (f->components>=GGL_LUMINANCE && - (i==GGLFormat::GREEN || i==GGLFormat::BLUE)) { - // destinations L formats don't have G or B - continue; - } - const int l = f->c[i].l; - const int h = f->c[i].h; - if (h && (c->state.mask.color & component_mask)) { - mask |= (((1<<(h-l))-1)<<l); - uint32_t u = pixel->c[i]; - int32_t pixelSize = pixel->s[i]; - if (pixelSize < (h-l)) { - u = expand(u, pixelSize, h-l); - pixelSize = h-l; - } - v = downshift_component(v, u, pixelSize, 0, h, l, 0, 0, dither); - } - } - - if ((c->state.mask.color != 0xF) || - (c->state.enables & GGL_ENABLE_LOGIC_OP)) { - uint32_t d = 0; - switch (f->size) { - case 1: d = *data; break; - case 2: d = *(uint16_t*)data; break; - case 3: d = (data[2]<<16)|(data[1]<<8)|data[0]; break; - case 4: d = GGL_RGBA_TO_HOST(*(uint32_t*)data); break; - } - if (c->state.enables & GGL_ENABLE_LOGIC_OP) { - v = logic_op(c->state.logic_op.opcode, v, d); - v &= mask; - } - v |= (d & ~mask); - } - - switch (f->size) { - case 1: *data = v; break; - case 2: *(uint16_t*)data = v; break; - case 3: - data[0] = v; - data[1] = v>>8; - data[2] = v>>16; - break; - case 4: *(uint32_t*)data = GGL_HOST_TO_RGBA(v); break; - } -} - -static uint32_t logic_op(int op, uint32_t s, uint32_t d) -{ - switch(op) { - case GGL_CLEAR: return 0; - case GGL_AND: return s & d; - case GGL_AND_REVERSE: return s & ~d; - case GGL_COPY: return s; - case GGL_AND_INVERTED: return ~s & d; - case GGL_NOOP: return d; - case GGL_XOR: return s ^ d; - case GGL_OR: return s | d; - case GGL_NOR: return ~(s | d); - case GGL_EQUIV: return ~(s ^ d); - case GGL_INVERT: return ~d; - case GGL_OR_REVERSE: return s | ~d; - case GGL_COPY_INVERTED: return ~s; - case GGL_OR_INVERTED: return ~s | d; - case GGL_NAND: return ~(s & d); - case GGL_SET: return ~0; - }; - return s; -} - - -uint32_t ggl_expand(uint32_t v, int sbits, int dbits) -{ - return expand(v, sbits, dbits); -} - -uint32_t ggl_pack_color(context_t* c, int32_t format, - GGLcolor r, GGLcolor g, GGLcolor b, GGLcolor a) -{ - const GGLFormat* f = &(c->formats[format]); - uint32_t p = 0; - const int32_t hbits = GGL_COLOR_BITS; - const int32_t lbits = GGL_COLOR_BITS - 8; - p = downshift_component(p, r, hbits, lbits, f->rh, f->rl, 0, 1, -1); - p = downshift_component(p, g, hbits, lbits, f->gh, f->gl, 0, 1, -1); - p = downshift_component(p, b, hbits, lbits, f->bh, f->bl, 0, 1, -1); - p = downshift_component(p, a, hbits, lbits, f->ah, f->al, 0, 1, -1); - switch (f->size) { - case 1: p |= p << 8; // fallthrough - case 2: p |= p << 16; - } - return p; -} - -// ---------------------------------------------------------------------------- - -// extract a component from a word -uint32_t extract(uint32_t v, int h, int l, int bits) -{ - assert(h); - if (l) { - v >>= l; - } - if (h != bits) { - v &= (1<<(h-l))-1; - } - return v; -} - -// expand a component from sbits to dbits -uint32_t expand(uint32_t v, int sbits, int dbits) -{ - if (dbits > sbits) { - assert(sbits); - if (sbits==1) { - v = (v<<dbits) - v; - } else { - if (dbits % sbits) { - v <<= (dbits-sbits); - dbits -= sbits; - do { - v |= v>>sbits; - dbits -= sbits; - sbits *= 2; - } while (dbits>0); - } else { - dbits -= sbits; - do { - v |= v<<sbits; - dbits -= sbits; - if (sbits*2 < dbits) { - sbits *= 2; - } - } while (dbits > 0); - } - } - } - return v; -} - -// downsample a component from sbits to dbits -// and shift / construct the pixel -uint32_t downshift_component( uint32_t in, uint32_t v, - int sh, int sl, // src - int dh, int dl, // dst - int ch, int cl, // clear - int dither) -{ - const int sbits = sh-sl; - const int dbits = dh-dl; - - assert(sbits>=dbits); - - - if (sbits>dbits) { - if (dither>=0) { - v -= (v>>dbits); // fix up - const int shift = (GGL_DITHER_BITS - (sbits-dbits)); - if (shift >= 0) v += (dither >> shift) << sl; - else v += (dither << (-shift)) << sl; - } else { - // don't do that right now, so we can reproduce the same - // artifacts we get on ARM (Where we don't do this) - // -> this is not really needed if we don't dither - //if (dBits > 1) { // result already OK if dBits==1 - // v -= (v>>dbits); // fix up - // v += 1 << ((sbits-dbits)-1); // rounding - //} - } - } - - - // we need to clear the high bits of the source - if (ch) { - v <<= 32-sh; - sl += 32-sh; - sh = 32; - } - - if (dl) { - if (cl || (sbits>dbits)) { - v >>= sh-dbits; - sl = 0; - sh = dbits; - in |= v<<dl; - } else { - // sbits==dbits and we don't need to clean the lower bits - // so we just have to shift the component to the right location - int shift = dh-sh; - in |= v<<shift; - } - } else { - // destination starts at bit 0 - // ie: sh-dh == sh-dbits - int shift = sh-dh; - if (shift > 0) in |= v>>shift; - else if (shift < 0) in |= v<<shift; - else in |= v; - } - return in; -} - -// ---------------------------------------------------------------------------- -}; // namespace android diff --git a/libpixelflinger/buffer.h b/libpixelflinger/buffer.h deleted file mode 100644 index 9c9e4bc726db8849ba3cc55bf9dce6bbed900971..0000000000000000000000000000000000000000 --- a/libpixelflinger/buffer.h +++ /dev/null @@ -1,39 +0,0 @@ -/* libs/pixelflinger/buffer.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_GGL_TEXTURE_H -#define ANDROID_GGL_TEXTURE_H - -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_texture(context_t* c); - -void ggl_set_surface(context_t* c, surface_t* dst, const GGLSurface* src); - -void ggl_pick_texture(context_t* c); -void ggl_pick_cb(context_t* c); - -uint32_t ggl_expand(uint32_t v, int sbits, int dbits); -uint32_t ggl_pack_color(context_t* c, int32_t format, - GGLcolor r, GGLcolor g, GGLcolor b, GGLcolor a); - -}; // namespace android - -#endif // ANDROID_GGL_TEXTURE_H diff --git a/libpixelflinger/clear.cpp b/libpixelflinger/clear.cpp deleted file mode 100644 index b962456353fafd4424ec3bf4aa7beda4eb1f8cac..0000000000000000000000000000000000000000 --- a/libpixelflinger/clear.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* libs/pixelflinger/clear.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <cutils/memory.h> - -#include "clear.h" -#include "buffer.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -static void ggl_clear(void* c, GGLbitfield mask); -static void ggl_clearColorx(void* c, - GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a); -static void ggl_clearDepthx(void* c, GGLclampx depth); -static void ggl_clearStencil(void* c, GGLint s); - -// ---------------------------------------------------------------------------- - -void ggl_init_clear(context_t* c) -{ - GGLContext& procs = *(GGLContext*)c; - GGL_INIT_PROC(procs, clear); - GGL_INIT_PROC(procs, clearColorx); - GGL_INIT_PROC(procs, clearDepthx); - GGL_INIT_PROC(procs, clearStencil); - c->state.clear.dirty = GGL_STENCIL_BUFFER_BIT | - GGL_COLOR_BUFFER_BIT | - GGL_DEPTH_BUFFER_BIT; - c->state.clear.depth = FIXED_ONE; -} - -// ---------------------------------------------------------------------------- - -static void memset2d(context_t* c, const surface_t& s, uint32_t packed, - uint32_t l, uint32_t t, uint32_t w, uint32_t h) -{ - const uint32_t size = c->formats[s.format].size; - const int32_t stride = s.stride * size; - uint8_t* dst = (uint8_t*)s.data + (l + t*s.stride)*size; - w *= size; - - if (ggl_likely(int32_t(w) == stride)) { - // clear the whole thing in one call - w *= h; - h = 1; - } - - switch (size) { - case 1: - do { - memset(dst, packed, w); - dst += stride; - } while(--h); - break; - case 2: - do { - android_memset16((uint16_t*)dst, packed, w); - dst += stride; - } while(--h); - break; - case 3: // XXX: 24-bit clear. - break; - case 4: - do { - android_memset32((uint32_t*)dst, packed, w); - dst += stride; - } while(--h); - break; - } -} - -static inline GGLfixed fixedToZ(GGLfixed z) { - return GGLfixed(((int64_t(z) << 16) - z) >> 16); -} - -static void ggl_clear(void* con, GGLbitfield mask) -{ - GGL_CONTEXT(c, con); - - // XXX: rgba-dithering, rgba-masking - // XXX: handle all formats of Z and S - - const uint32_t l = c->state.scissor.left; - const uint32_t t = c->state.scissor.top; - uint32_t w = c->state.scissor.right - l; - uint32_t h = c->state.scissor.bottom - t; - - if (!w || !h) - return; - - // unexsiting buffers have no effect... - if (c->state.buffers.color.format == 0) - mask &= ~GGL_COLOR_BUFFER_BIT; - - if (c->state.buffers.depth.format == 0) - mask &= ~GGL_DEPTH_BUFFER_BIT; - - if (c->state.buffers.stencil.format == 0) - mask &= ~GGL_STENCIL_BUFFER_BIT; - - if (mask & GGL_COLOR_BUFFER_BIT) { - if (c->state.clear.dirty & GGL_COLOR_BUFFER_BIT) { - c->state.clear.dirty &= ~GGL_COLOR_BUFFER_BIT; - - uint32_t colorPacked = ggl_pack_color(c, - c->state.buffers.color.format, - gglFixedToIteratedColor(c->state.clear.r), - gglFixedToIteratedColor(c->state.clear.g), - gglFixedToIteratedColor(c->state.clear.b), - gglFixedToIteratedColor(c->state.clear.a)); - - c->state.clear.colorPacked = GGL_HOST_TO_RGBA(colorPacked); - } - const uint32_t packed = c->state.clear.colorPacked; - memset2d(c, c->state.buffers.color, packed, l, t, w, h); - } - if (mask & GGL_DEPTH_BUFFER_BIT) { - if (c->state.clear.dirty & GGL_DEPTH_BUFFER_BIT) { - c->state.clear.dirty &= ~GGL_DEPTH_BUFFER_BIT; - uint32_t depth = fixedToZ(c->state.clear.depth); - c->state.clear.depthPacked = (depth<<16)|depth; - } - const uint32_t packed = c->state.clear.depthPacked; - memset2d(c, c->state.buffers.depth, packed, l, t, w, h); - } - - // XXX: do stencil buffer -} - -static void ggl_clearColorx(void* con, - GGLclampx r, GGLclampx g, GGLclampx b, GGLclampx a) -{ - GGL_CONTEXT(c, con); - c->state.clear.r = gglClampx(r); - c->state.clear.g = gglClampx(g); - c->state.clear.b = gglClampx(b); - c->state.clear.a = gglClampx(a); - c->state.clear.dirty |= GGL_COLOR_BUFFER_BIT; -} - -static void ggl_clearDepthx(void* con, GGLclampx depth) -{ - GGL_CONTEXT(c, con); - c->state.clear.depth = gglClampx(depth); - c->state.clear.dirty |= GGL_DEPTH_BUFFER_BIT; -} - -static void ggl_clearStencil(void* con, GGLint s) -{ - GGL_CONTEXT(c, con); - c->state.clear.stencil = s; - c->state.clear.dirty |= GGL_STENCIL_BUFFER_BIT; -} - -}; // namespace android diff --git a/libpixelflinger/clear.h b/libpixelflinger/clear.h deleted file mode 100644 index b071df0a76a08e67b59fddcc2db4df14c44df8d0..0000000000000000000000000000000000000000 --- a/libpixelflinger/clear.h +++ /dev/null @@ -1,30 +0,0 @@ -/* libs/pixelflinger/clear.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_GGL_CLEAR_H -#define ANDROID_GGL_CLEAR_H - -#include <pixelflinger/pixelflinger.h> -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_clear(context_t* c); - -}; // namespace android - -#endif // ANDROID_GGL_CLEAR_H diff --git a/libpixelflinger/codeflinger/ARMAssembler.cpp b/libpixelflinger/codeflinger/ARMAssembler.cpp deleted file mode 100644 index ff7b0b3e0d6b91dc9b8b9972a863d4719ed596cc..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssembler.cpp +++ /dev/null @@ -1,428 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssembler.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "ARMAssembler" - -#include <stdio.h> -#include <stdlib.h> -#include <cutils/log.h> -#include <cutils/properties.h> - -#if defined(WITH_LIB_HARDWARE) -#include <hardware_legacy/qemu_tracing.h> -#endif - -#include <private/pixelflinger/ggl_context.h> - -#include "codeflinger/ARMAssembler.h" -#include "codeflinger/CodeCache.h" -#include "codeflinger/disassem.h" - -// ---------------------------------------------------------------------------- - -namespace android { - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark ARMAssembler... -#endif - -ARMAssembler::ARMAssembler(const sp<Assembly>& assembly) - : ARMAssemblerInterface(), - mAssembly(assembly) -{ - mBase = mPC = (uint32_t *)assembly->base(); - mDuration = ggl_system_time(); -#if defined(WITH_LIB_HARDWARE) - mQemuTracing = true; -#endif -} - -ARMAssembler::~ARMAssembler() -{ -} - -uint32_t* ARMAssembler::pc() const -{ - return mPC; -} - -uint32_t* ARMAssembler::base() const -{ - return mBase; -} - -void ARMAssembler::reset() -{ - mBase = mPC = (uint32_t *)mAssembly->base(); - mBranchTargets.clear(); - mLabels.clear(); - mLabelsInverseMapping.clear(); - mComments.clear(); -} - -// ---------------------------------------------------------------------------- - -void ARMAssembler::disassemble(const char* name) -{ - if (name) { - printf("%s:\n", name); - } - size_t count = pc()-base(); - uint32_t* i = base(); - while (count--) { - ssize_t label = mLabelsInverseMapping.indexOfKey(i); - if (label >= 0) { - printf("%s:\n", mLabelsInverseMapping.valueAt(label)); - } - ssize_t comment = mComments.indexOfKey(i); - if (comment >= 0) { - printf("; %s\n", mComments.valueAt(comment)); - } - printf("%08x: %08x ", int(i), int(i[0])); - ::disassemble((u_int)i); - i++; - } -} - -void ARMAssembler::comment(const char* string) -{ - mComments.add(mPC, string); -} - -void ARMAssembler::label(const char* theLabel) -{ - mLabels.add(theLabel, mPC); - mLabelsInverseMapping.add(mPC, theLabel); -} - -void ARMAssembler::B(int cc, const char* label) -{ - mBranchTargets.add(branch_target_t(label, mPC)); - *mPC++ = (cc<<28) | (0xA<<24) | 0; -} - -void ARMAssembler::BL(int cc, const char* label) -{ - mBranchTargets.add(branch_target_t(label, mPC)); - *mPC++ = (cc<<28) | (0xB<<24) | 0; -} - -#if 0 -#pragma mark - -#pragma mark Prolog/Epilog & Generate... -#endif - - -void ARMAssembler::prolog() -{ - // write dummy prolog code - mPrologPC = mPC; - STM(AL, FD, SP, 1, LSAVED); -} - -void ARMAssembler::epilog(uint32_t touched) -{ - touched &= LSAVED; - if (touched) { - // write prolog code - uint32_t* pc = mPC; - mPC = mPrologPC; - STM(AL, FD, SP, 1, touched | LLR); - mPC = pc; - // write epilog code - LDM(AL, FD, SP, 1, touched | LLR); - BX(AL, LR); - } else { // heh, no registers to save! - // write prolog code - uint32_t* pc = mPC; - mPC = mPrologPC; - MOV(AL, 0, R0, R0); // NOP - mPC = pc; - // write epilog code - BX(AL, LR); - } -} - -int ARMAssembler::generate(const char* name) -{ - // fixup all the branches - size_t count = mBranchTargets.size(); - while (count--) { - const branch_target_t& bt = mBranchTargets[count]; - uint32_t* target_pc = mLabels.valueFor(bt.label); - LOG_ALWAYS_FATAL_IF(!target_pc, - "error resolving branch targets, target_pc is null"); - int32_t offset = int32_t(target_pc - (bt.pc+2)); - *bt.pc |= offset & 0xFFFFFF; - } - - mAssembly->resize( int(pc()-base())*4 ); - - // the instruction cache is flushed by CodeCache - const int64_t duration = ggl_system_time() - mDuration; - const char * const format = "generated %s (%d ins) at [%p:%p] in %lld ns\n"; - LOGI(format, name, int(pc()-base()), base(), pc(), duration); - -#if defined(WITH_LIB_HARDWARE) - if (__builtin_expect(mQemuTracing, 0)) { - int err = qemu_add_mapping(int(base()), name); - mQemuTracing = (err >= 0); - } -#endif - - char value[PROPERTY_VALUE_MAX]; - property_get("debug.pf.disasm", value, "0"); - if (atoi(value) != 0) { - printf(format, name, int(pc()-base()), base(), pc(), duration); - disassemble(name); - } - - return NO_ERROR; -} - -uint32_t* ARMAssembler::pcForLabel(const char* label) -{ - return mLabels.valueFor(label); -} - -// ---------------------------------------------------------------------------- - -#if 0 -#pragma mark - -#pragma mark Data Processing... -#endif - -void ARMAssembler::dataProcessing(int opcode, int cc, - int s, int Rd, int Rn, uint32_t Op2) -{ - *mPC++ = (cc<<28) | (opcode<<21) | (s<<20) | (Rn<<16) | (Rd<<12) | Op2; -} - -#if 0 -#pragma mark - -#pragma mark Multiply... -#endif - -// multiply... -void ARMAssembler::MLA(int cc, int s, - int Rd, int Rm, int Rs, int Rn) { - if (Rd == Rm) { int t = Rm; Rm=Rs; Rs=t; } - LOG_FATAL_IF(Rd==Rm, "MLA(r%u,r%u,r%u,r%u)", Rd,Rm,Rs,Rn); - *mPC++ = (cc<<28) | (1<<21) | (s<<20) | - (Rd<<16) | (Rn<<12) | (Rs<<8) | 0x90 | Rm; -} -void ARMAssembler::MUL(int cc, int s, - int Rd, int Rm, int Rs) { - if (Rd == Rm) { int t = Rm; Rm=Rs; Rs=t; } - LOG_FATAL_IF(Rd==Rm, "MUL(r%u,r%u,r%u)", Rd,Rm,Rs); - *mPC++ = (cc<<28) | (s<<20) | (Rd<<16) | (Rs<<8) | 0x90 | Rm; -} -void ARMAssembler::UMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, - "UMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); - *mPC++ = (cc<<28) | (1<<23) | (s<<20) | - (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; -} -void ARMAssembler::UMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, - "UMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); - *mPC++ = (cc<<28) | (1<<23) | (1<<21) | (s<<20) | - (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; -} -void ARMAssembler::SMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, - "SMULL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); - *mPC++ = (cc<<28) | (1<<23) | (1<<22) | (s<<20) | - (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; -} -void ARMAssembler::SMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - LOG_FATAL_IF(RdLo==Rm || RdHi==Rm || RdLo==RdHi, - "SMUAL(r%u,r%u,r%u,r%u)", RdLo,RdHi,Rm,Rs); - *mPC++ = (cc<<28) | (1<<23) | (1<<22) | (1<<21) | (s<<20) | - (RdHi<<16) | (RdLo<<12) | (Rs<<8) | 0x90 | Rm; -} - -#if 0 -#pragma mark - -#pragma mark Branches... -#endif - -// branches... -void ARMAssembler::B(int cc, uint32_t* pc) -{ - int32_t offset = int32_t(pc - (mPC+2)); - *mPC++ = (cc<<28) | (0xA<<24) | (offset & 0xFFFFFF); -} - -void ARMAssembler::BL(int cc, uint32_t* pc) -{ - int32_t offset = int32_t(pc - (mPC+2)); - *mPC++ = (cc<<28) | (0xB<<24) | (offset & 0xFFFFFF); -} - -void ARMAssembler::BX(int cc, int Rn) -{ - *mPC++ = (cc<<28) | 0x12FFF10 | Rn; -} - -#if 0 -#pragma mark - -#pragma mark Data Transfer... -#endif - -// data transfert... -void ARMAssembler::LDR(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<26) | (1<<20) | (Rn<<16) | (Rd<<12) | offset; -} -void ARMAssembler::LDRB(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<26) | (1<<22) | (1<<20) | (Rn<<16) | (Rd<<12) | offset; -} -void ARMAssembler::STR(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<26) | (Rn<<16) | (Rd<<12) | offset; -} -void ARMAssembler::STRB(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<26) | (1<<22) | (Rn<<16) | (Rd<<12) | offset; -} - -void ARMAssembler::LDRH(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xB0 | offset; -} -void ARMAssembler::LDRSB(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xD0 | offset; -} -void ARMAssembler::LDRSH(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (1<<20) | (Rn<<16) | (Rd<<12) | 0xF0 | offset; -} -void ARMAssembler::STRH(int cc, int Rd, int Rn, uint32_t offset) { - *mPC++ = (cc<<28) | (Rn<<16) | (Rd<<12) | 0xB0 | offset; -} - -#if 0 -#pragma mark - -#pragma mark Block Data Transfer... -#endif - -// block data transfer... -void ARMAssembler::LDM(int cc, int dir, - int Rn, int W, uint32_t reg_list) -{ // ED FD EA FA IB IA DB DA - const uint8_t P[8] = { 1, 0, 1, 0, 1, 0, 1, 0 }; - const uint8_t U[8] = { 1, 1, 0, 0, 1, 1, 0, 0 }; - *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) | - (uint32_t(U[dir])<<23) | (1<<20) | (W<<21) | (Rn<<16) | reg_list; -} - -void ARMAssembler::STM(int cc, int dir, - int Rn, int W, uint32_t reg_list) -{ // FA EA FD ED IB IA DB DA - const uint8_t P[8] = { 0, 1, 0, 1, 1, 0, 1, 0 }; - const uint8_t U[8] = { 0, 0, 1, 1, 1, 1, 0, 0 }; - *mPC++ = (cc<<28) | (4<<25) | (uint32_t(P[dir])<<24) | - (uint32_t(U[dir])<<23) | (0<<20) | (W<<21) | (Rn<<16) | reg_list; -} - -#if 0 -#pragma mark - -#pragma mark Special... -#endif - -// special... -void ARMAssembler::SWP(int cc, int Rn, int Rd, int Rm) { - *mPC++ = (cc<<28) | (2<<23) | (Rn<<16) | (Rd << 12) | 0x90 | Rm; -} -void ARMAssembler::SWPB(int cc, int Rn, int Rd, int Rm) { - *mPC++ = (cc<<28) | (2<<23) | (1<<22) | (Rn<<16) | (Rd << 12) | 0x90 | Rm; -} -void ARMAssembler::SWI(int cc, uint32_t comment) { - *mPC++ = (cc<<28) | (0xF<<24) | comment; -} - -#if 0 -#pragma mark - -#pragma mark DSP instructions... -#endif - -// DSP instructions... -void ARMAssembler::PLD(int Rn, uint32_t offset) { - LOG_ALWAYS_FATAL_IF(!((offset&(1<<24)) && !(offset&(1<<21))), - "PLD only P=1, W=0"); - *mPC++ = 0xF550F000 | (Rn<<16) | offset; -} - -void ARMAssembler::CLZ(int cc, int Rd, int Rm) -{ - *mPC++ = (cc<<28) | 0x16F0F10| (Rd<<12) | Rm; -} - -void ARMAssembler::QADD(int cc, int Rd, int Rm, int Rn) -{ - *mPC++ = (cc<<28) | 0x1000050 | (Rn<<16) | (Rd<<12) | Rm; -} - -void ARMAssembler::QDADD(int cc, int Rd, int Rm, int Rn) -{ - *mPC++ = (cc<<28) | 0x1400050 | (Rn<<16) | (Rd<<12) | Rm; -} - -void ARMAssembler::QSUB(int cc, int Rd, int Rm, int Rn) -{ - *mPC++ = (cc<<28) | 0x1200050 | (Rn<<16) | (Rd<<12) | Rm; -} - -void ARMAssembler::QDSUB(int cc, int Rd, int Rm, int Rn) -{ - *mPC++ = (cc<<28) | 0x1600050 | (Rn<<16) | (Rd<<12) | Rm; -} - -void ARMAssembler::SMUL(int cc, int xy, - int Rd, int Rm, int Rs) -{ - *mPC++ = (cc<<28) | 0x1600080 | (Rd<<16) | (Rs<<8) | (xy<<4) | Rm; -} - -void ARMAssembler::SMULW(int cc, int y, - int Rd, int Rm, int Rs) -{ - *mPC++ = (cc<<28) | 0x12000A0 | (Rd<<16) | (Rs<<8) | (y<<4) | Rm; -} - -void ARMAssembler::SMLA(int cc, int xy, - int Rd, int Rm, int Rs, int Rn) -{ - *mPC++ = (cc<<28) | 0x1000080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (xy<<4) | Rm; -} - -void ARMAssembler::SMLAL(int cc, int xy, - int RdHi, int RdLo, int Rs, int Rm) -{ - *mPC++ = (cc<<28) | 0x1400080 | (RdHi<<16) | (RdLo<<12) | (Rs<<8) | (xy<<4) | Rm; -} - -void ARMAssembler::SMLAW(int cc, int y, - int Rd, int Rm, int Rs, int Rn) -{ - *mPC++ = (cc<<28) | 0x1200080 | (Rd<<16) | (Rn<<12) | (Rs<<8) | (y<<4) | Rm; -} - -}; // namespace android - diff --git a/libpixelflinger/codeflinger/ARMAssembler.h b/libpixelflinger/codeflinger/ARMAssembler.h deleted file mode 100644 index 8837e07add5066f54ce8942748eb3d4f98a78dca..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssembler.h +++ /dev/null @@ -1,155 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssembler.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef ANDROID_ARMASSEMBLER_H -#define ANDROID_ARMASSEMBLER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <utils/Vector.h> -#include <utils/KeyedVector.h> - -#include "tinyutils/smartpointer.h" -#include "codeflinger/ARMAssemblerInterface.h" -#include "codeflinger/CodeCache.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -class ARMAssembler : public ARMAssemblerInterface -{ -public: - ARMAssembler(const sp<Assembly>& assembly); - virtual ~ARMAssembler(); - - uint32_t* base() const; - uint32_t* pc() const; - - - void disassemble(const char* name); - - // ------------------------------------------------------------------------ - // ARMAssemblerInterface... - // ------------------------------------------------------------------------ - - virtual void reset(); - - virtual int generate(const char* name); - - virtual void prolog(); - virtual void epilog(uint32_t touched); - virtual void comment(const char* string); - - virtual void dataProcessing(int opcode, int cc, int s, - int Rd, int Rn, - uint32_t Op2); - virtual void MLA(int cc, int s, - int Rd, int Rm, int Rs, int Rn); - virtual void MUL(int cc, int s, - int Rd, int Rm, int Rs); - virtual void UMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void UMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void SMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void SMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - - virtual void B(int cc, uint32_t* pc); - virtual void BL(int cc, uint32_t* pc); - virtual void BX(int cc, int Rn); - virtual void label(const char* theLabel); - virtual void B(int cc, const char* label); - virtual void BL(int cc, const char* label); - - virtual uint32_t* pcForLabel(const char* label); - - virtual void LDR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void LDRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void STR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void STRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void LDRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDRSB(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDRSH(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void STRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDM(int cc, int dir, - int Rn, int W, uint32_t reg_list); - virtual void STM(int cc, int dir, - int Rn, int W, uint32_t reg_list); - - virtual void SWP(int cc, int Rn, int Rd, int Rm); - virtual void SWPB(int cc, int Rn, int Rd, int Rm); - virtual void SWI(int cc, uint32_t comment); - - virtual void PLD(int Rn, uint32_t offset); - virtual void CLZ(int cc, int Rd, int Rm); - virtual void QADD(int cc, int Rd, int Rm, int Rn); - virtual void QDADD(int cc, int Rd, int Rm, int Rn); - virtual void QSUB(int cc, int Rd, int Rm, int Rn); - virtual void QDSUB(int cc, int Rd, int Rm, int Rn); - virtual void SMUL(int cc, int xy, - int Rd, int Rm, int Rs); - virtual void SMULW(int cc, int y, - int Rd, int Rm, int Rs); - virtual void SMLA(int cc, int xy, - int Rd, int Rm, int Rs, int Rn); - virtual void SMLAL(int cc, int xy, - int RdHi, int RdLo, int Rs, int Rm); - virtual void SMLAW(int cc, int y, - int Rd, int Rm, int Rs, int Rn); - -private: - ARMAssembler(const ARMAssembler& rhs); - ARMAssembler& operator = (const ARMAssembler& rhs); - - sp<Assembly> mAssembly; - uint32_t* mBase; - uint32_t* mPC; - uint32_t* mPrologPC; - int64_t mDuration; -#if defined(WITH_LIB_HARDWARE) - bool mQemuTracing; -#endif - - struct branch_target_t { - inline branch_target_t() : label(0), pc(0) { } - inline branch_target_t(const char* l, uint32_t* p) - : label(l), pc(p) { } - const char* label; - uint32_t* pc; - }; - - Vector<branch_target_t> mBranchTargets; - KeyedVector< const char*, uint32_t* > mLabels; - KeyedVector< uint32_t*, const char* > mLabelsInverseMapping; - KeyedVector< uint32_t*, const char* > mComments; -}; - -}; // namespace android - -#endif //ANDROID_ARMASSEMBLER_H diff --git a/libpixelflinger/codeflinger/ARMAssemblerInterface.cpp b/libpixelflinger/codeflinger/ARMAssemblerInterface.cpp deleted file mode 100644 index 7fa0de0a81e920783c60f62a6522732055b70c38..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssemblerInterface.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssemblerInterface.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <errno.h> -#include <stdlib.h> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/log.h> -#include "codeflinger/ARMAssemblerInterface.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -ARMAssemblerInterface::~ARMAssemblerInterface() -{ -} - -int ARMAssemblerInterface::buildImmediate( - uint32_t immediate, uint32_t& rot, uint32_t& imm) -{ - rot = 0; - imm = immediate; - if (imm > 0x7F) { // skip the easy cases - while (!(imm&3) || (imm&0xFC000000)) { - uint32_t newval; - newval = imm >> 2; - newval |= (imm&3) << 30; - imm = newval; - rot += 2; - if (rot == 32) { - rot = 0; - break; - } - } - } - rot = (16 - (rot>>1)) & 0xF; - - if (imm>=0x100) - return -EINVAL; - - if (((imm>>(rot<<1)) | (imm<<(32-(rot<<1)))) != immediate) - return -1; - - return 0; -} - -// shifters... - -bool ARMAssemblerInterface::isValidImmediate(uint32_t immediate) -{ - uint32_t rot, imm; - return buildImmediate(immediate, rot, imm) == 0; -} - -uint32_t ARMAssemblerInterface::imm(uint32_t immediate) -{ - uint32_t rot, imm; - int err = buildImmediate(immediate, rot, imm); - - LOG_ALWAYS_FATAL_IF(err==-EINVAL, - "immediate %08x cannot be encoded", - immediate); - - LOG_ALWAYS_FATAL_IF(err, - "immediate (%08x) encoding bogus!", - immediate); - - return (1<<25) | (rot<<8) | imm; -} - -uint32_t ARMAssemblerInterface::reg_imm(int Rm, int type, uint32_t shift) -{ - return ((shift&0x1F)<<7) | ((type&0x3)<<5) | (Rm&0xF); -} - -uint32_t ARMAssemblerInterface::reg_rrx(int Rm) -{ - return (ROR<<5) | (Rm&0xF); -} - -uint32_t ARMAssemblerInterface::reg_reg(int Rm, int type, int Rs) -{ - return ((Rs&0xF)<<8) | ((type&0x3)<<5) | (1<<4) | (Rm&0xF); -} - -// addressing modes... -// LDR(B)/STR(B)/PLD (immediate and Rm can be negative, which indicate U=0) -uint32_t ARMAssemblerInterface::immed12_pre(int32_t immed12, int W) -{ - LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, - "LDR(B)/STR(B)/PLD immediate too big (%08x)", - immed12); - return (1<<24) | (((uint32_t(immed12)>>31)^1)<<23) | - ((W&1)<<21) | (abs(immed12)&0x7FF); -} - -uint32_t ARMAssemblerInterface::immed12_post(int32_t immed12) -{ - LOG_ALWAYS_FATAL_IF(abs(immed12) >= 0x800, - "LDR(B)/STR(B)/PLD immediate too big (%08x)", - immed12); - - return (((uint32_t(immed12)>>31)^1)<<23) | (abs(immed12)&0x7FF); -} - -uint32_t ARMAssemblerInterface::reg_scale_pre(int Rm, int type, - uint32_t shift, int W) -{ - return (1<<25) | (1<<24) | - (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | - reg_imm(abs(Rm), type, shift); -} - -uint32_t ARMAssemblerInterface::reg_scale_post(int Rm, int type, uint32_t shift) -{ - return (1<<25) | (((uint32_t(Rm)>>31)^1)<<23) | reg_imm(abs(Rm), type, shift); -} - -// LDRH/LDRSB/LDRSH/STRH (immediate and Rm can be negative, which indicate U=0) -uint32_t ARMAssemblerInterface::immed8_pre(int32_t immed8, int W) -{ - uint32_t offset = abs(immed8); - - LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, - "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", - immed8); - - return (1<<24) | (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | - ((W&1)<<21) | (((offset&0xF0)<<4)|(offset&0xF)); -} - -uint32_t ARMAssemblerInterface::immed8_post(int32_t immed8) -{ - uint32_t offset = abs(immed8); - - LOG_ALWAYS_FATAL_IF(abs(immed8) >= 0x100, - "LDRH/LDRSB/LDRSH/STRH immediate too big (%08x)", - immed8); - - return (1<<22) | (((uint32_t(immed8)>>31)^1)<<23) | - (((offset&0xF0)<<4) | (offset&0xF)); -} - -uint32_t ARMAssemblerInterface::reg_pre(int Rm, int W) -{ - return (1<<24) | (((uint32_t(Rm)>>31)^1)<<23) | ((W&1)<<21) | (abs(Rm)&0xF); -} - -uint32_t ARMAssemblerInterface::reg_post(int Rm) -{ - return (((uint32_t(Rm)>>31)^1)<<23) | (abs(Rm)&0xF); -} - - -}; // namespace android - diff --git a/libpixelflinger/codeflinger/ARMAssemblerInterface.h b/libpixelflinger/codeflinger/ARMAssemblerInterface.h deleted file mode 100644 index 465b3bd9d98bde3041fe4694a2c7f2e72eb1950d..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssemblerInterface.h +++ /dev/null @@ -1,324 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssemblerInterface.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_ARMASSEMBLER_INTERFACE_H -#define ANDROID_ARMASSEMBLER_INTERFACE_H - -#include <stdint.h> -#include <sys/types.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -class ARMAssemblerInterface -{ -public: - virtual ~ARMAssemblerInterface(); - - enum { - EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV, - HS = CS, - LO = CC - }; - enum { - S = 1 - }; - enum { - LSL, LSR, ASR, ROR - }; - enum { - ED, FD, EA, FA, - IB, IA, DB, DA - }; - enum { - R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, - SP = R13, - LR = R14, - PC = R15 - }; - enum { - #define LIST(rr) L##rr=1<<rr - LIST(R0), LIST(R1), LIST(R2), LIST(R3), LIST(R4), LIST(R5), LIST(R6), - LIST(R7), LIST(R8), LIST(R9), LIST(R10), LIST(R11), LIST(R12), - LIST(R13), LIST(R14), LIST(R15), - LIST(SP), LIST(LR), LIST(PC), - #undef LIST - LSAVED = LR4|LR5|LR6|LR7|LR8|LR9|LR10|LR11 | LLR - }; - - // ----------------------------------------------------------------------- - // shifters and addressing modes - // ----------------------------------------------------------------------- - - // shifters... - static bool isValidImmediate(uint32_t immed); - static int buildImmediate(uint32_t i, uint32_t& rot, uint32_t& imm); - - static uint32_t imm(uint32_t immediate); - static uint32_t reg_imm(int Rm, int type, uint32_t shift); - static uint32_t reg_rrx(int Rm); - static uint32_t reg_reg(int Rm, int type, int Rs); - - // addressing modes... - // LDR(B)/STR(B)/PLD - // (immediate and Rm can be negative, which indicates U=0) - static uint32_t immed12_pre(int32_t immed12, int W=0); - static uint32_t immed12_post(int32_t immed12); - static uint32_t reg_scale_pre(int Rm, int type=0, uint32_t shift=0, int W=0); - static uint32_t reg_scale_post(int Rm, int type=0, uint32_t shift=0); - - // LDRH/LDRSB/LDRSH/STRH - // (immediate and Rm can be negative, which indicates U=0) - static uint32_t immed8_pre(int32_t immed8, int W=0); - static uint32_t immed8_post(int32_t immed8); - static uint32_t reg_pre(int Rm, int W=0); - static uint32_t reg_post(int Rm); - - // ----------------------------------------------------------------------- - // basic instructions & code generation - // ----------------------------------------------------------------------- - - // generate the code - virtual void reset() = 0; - virtual int generate(const char* name) = 0; - virtual void disassemble(const char* name) = 0; - - // construct prolog and epilog - virtual void prolog() = 0; - virtual void epilog(uint32_t touched) = 0; - virtual void comment(const char* string) = 0; - - // data processing... - enum { - opAND, opEOR, opSUB, opRSB, opADD, opADC, opSBC, opRSC, - opTST, opTEQ, opCMP, opCMN, opORR, opMOV, opBIC, opMVN - }; - - virtual void - dataProcessing( int opcode, int cc, int s, - int Rd, int Rn, - uint32_t Op2) = 0; - - // multiply... - virtual void MLA(int cc, int s, - int Rd, int Rm, int Rs, int Rn) = 0; - virtual void MUL(int cc, int s, - int Rd, int Rm, int Rs) = 0; - virtual void UMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) = 0; - virtual void UMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) = 0; - virtual void SMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) = 0; - virtual void SMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) = 0; - - // branches... - virtual void B(int cc, uint32_t* pc) = 0; - virtual void BL(int cc, uint32_t* pc) = 0; - virtual void BX(int cc, int Rn) = 0; - - virtual void label(const char* theLabel) = 0; - virtual void B(int cc, const char* label) = 0; - virtual void BL(int cc, const char* label) = 0; - - // valid only after generate() has been called - virtual uint32_t* pcForLabel(const char* label) = 0; - - // data transfer... - virtual void LDR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)) = 0; - virtual void LDRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)) = 0; - virtual void STR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)) = 0; - virtual void STRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)) = 0; - - virtual void LDRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)) = 0; - virtual void LDRSB(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)) = 0; - virtual void LDRSH(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)) = 0; - virtual void STRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)) = 0; - - // block data transfer... - virtual void LDM(int cc, int dir, - int Rn, int W, uint32_t reg_list) = 0; - virtual void STM(int cc, int dir, - int Rn, int W, uint32_t reg_list) = 0; - - // special... - virtual void SWP(int cc, int Rn, int Rd, int Rm) = 0; - virtual void SWPB(int cc, int Rn, int Rd, int Rm) = 0; - virtual void SWI(int cc, uint32_t comment) = 0; - - // DSP instructions... - enum { - // B=0, T=1 - // yx - xyBB = 0, // 0000, - xyTB = 2, // 0010, - xyBT = 4, // 0100, - xyTT = 6, // 0110, - yB = 0, // 0000, - yT = 4, // 0100 - }; - - virtual void PLD(int Rn, uint32_t offset) = 0; - - virtual void CLZ(int cc, int Rd, int Rm) = 0; - - virtual void QADD(int cc, int Rd, int Rm, int Rn) = 0; - virtual void QDADD(int cc, int Rd, int Rm, int Rn) = 0; - virtual void QSUB(int cc, int Rd, int Rm, int Rn) = 0; - virtual void QDSUB(int cc, int Rd, int Rm, int Rn) = 0; - - virtual void SMUL(int cc, int xy, - int Rd, int Rm, int Rs) = 0; - virtual void SMULW(int cc, int y, - int Rd, int Rm, int Rs) = 0; - virtual void SMLA(int cc, int xy, - int Rd, int Rm, int Rs, int Rn) = 0; - virtual void SMLAL(int cc, int xy, - int RdHi, int RdLo, int Rs, int Rm) = 0; - virtual void SMLAW(int cc, int y, - int Rd, int Rm, int Rs, int Rn) = 0; - - // ----------------------------------------------------------------------- - // convenience... - // ----------------------------------------------------------------------- - inline void - ADC(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opADC, cc, s, Rd, Rn, Op2); - } - inline void - ADD(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opADD, cc, s, Rd, Rn, Op2); - } - inline void - AND(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opAND, cc, s, Rd, Rn, Op2); - } - inline void - BIC(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opBIC, cc, s, Rd, Rn, Op2); - } - inline void - EOR(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opEOR, cc, s, Rd, Rn, Op2); - } - inline void - MOV(int cc, int s, int Rd, uint32_t Op2) { - dataProcessing(opMOV, cc, s, Rd, 0, Op2); - } - inline void - MVN(int cc, int s, int Rd, uint32_t Op2) { - dataProcessing(opMVN, cc, s, Rd, 0, Op2); - } - inline void - ORR(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opORR, cc, s, Rd, Rn, Op2); - } - inline void - RSB(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opRSB, cc, s, Rd, Rn, Op2); - } - inline void - RSC(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opRSC, cc, s, Rd, Rn, Op2); - } - inline void - SBC(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opSBC, cc, s, Rd, Rn, Op2); - } - inline void - SUB(int cc, int s, int Rd, int Rn, uint32_t Op2) { - dataProcessing(opSUB, cc, s, Rd, Rn, Op2); - } - inline void - TEQ(int cc, int Rn, uint32_t Op2) { - dataProcessing(opTEQ, cc, 1, 0, Rn, Op2); - } - inline void - TST(int cc, int Rn, uint32_t Op2) { - dataProcessing(opTST, cc, 1, 0, Rn, Op2); - } - inline void - CMP(int cc, int Rn, uint32_t Op2) { - dataProcessing(opCMP, cc, 1, 0, Rn, Op2); - } - inline void - CMN(int cc, int Rn, uint32_t Op2) { - dataProcessing(opCMN, cc, 1, 0, Rn, Op2); - } - - inline void SMULBB(int cc, int Rd, int Rm, int Rs) { - SMUL(cc, xyBB, Rd, Rm, Rs); } - inline void SMULTB(int cc, int Rd, int Rm, int Rs) { - SMUL(cc, xyTB, Rd, Rm, Rs); } - inline void SMULBT(int cc, int Rd, int Rm, int Rs) { - SMUL(cc, xyBT, Rd, Rm, Rs); } - inline void SMULTT(int cc, int Rd, int Rm, int Rs) { - SMUL(cc, xyTT, Rd, Rm, Rs); } - - inline void SMULWB(int cc, int Rd, int Rm, int Rs) { - SMULW(cc, yB, Rd, Rm, Rs); } - inline void SMULWT(int cc, int Rd, int Rm, int Rs) { - SMULW(cc, yT, Rd, Rm, Rs); } - - inline void - SMLABB(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLA(cc, xyBB, Rd, Rm, Rs, Rn); } - inline void - SMLATB(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLA(cc, xyTB, Rd, Rm, Rs, Rn); } - inline void - SMLABT(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLA(cc, xyBT, Rd, Rm, Rs, Rn); } - inline void - SMLATT(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLA(cc, xyTT, Rd, Rm, Rs, Rn); } - - inline void - SMLALBB(int cc, int RdHi, int RdLo, int Rs, int Rm) { - SMLAL(cc, xyBB, RdHi, RdLo, Rs, Rm); } - inline void - SMLALTB(int cc, int RdHi, int RdLo, int Rs, int Rm) { - SMLAL(cc, xyTB, RdHi, RdLo, Rs, Rm); } - inline void - SMLALBT(int cc, int RdHi, int RdLo, int Rs, int Rm) { - SMLAL(cc, xyBT, RdHi, RdLo, Rs, Rm); } - inline void - SMLALTT(int cc, int RdHi, int RdLo, int Rs, int Rm) { - SMLAL(cc, xyTT, RdHi, RdLo, Rs, Rm); } - - inline void - SMLAWB(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLAW(cc, yB, Rd, Rm, Rs, Rn); } - inline void - SMLAWT(int cc, int Rd, int Rm, int Rs, int Rn) { - SMLAW(cc, yT, Rd, Rm, Rs, Rn); } -}; - -}; // namespace android - -#endif //ANDROID_ARMASSEMBLER_INTERFACE_H diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp b/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp deleted file mode 100644 index 18c46186499704016d39d199eddbd9056f1ab46d..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.cpp +++ /dev/null @@ -1,200 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssemblerProxy.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <stdint.h> -#include <sys/types.h> - -#include "codeflinger/ARMAssemblerProxy.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -ARMAssemblerProxy::ARMAssemblerProxy() - : mTarget(0) -{ -} - -ARMAssemblerProxy::ARMAssemblerProxy(ARMAssemblerInterface* target) - : mTarget(target) -{ -} - -ARMAssemblerProxy::~ARMAssemblerProxy() -{ - delete mTarget; -} - -void ARMAssemblerProxy::setTarget(ARMAssemblerInterface* target) -{ - delete mTarget; - mTarget = target; -} - -void ARMAssemblerProxy::reset() { - mTarget->reset(); -} -int ARMAssemblerProxy::generate(const char* name) { - return mTarget->generate(name); -} -void ARMAssemblerProxy::disassemble(const char* name) { - return mTarget->disassemble(name); -} -void ARMAssemblerProxy::prolog() { - mTarget->prolog(); -} -void ARMAssemblerProxy::epilog(uint32_t touched) { - mTarget->epilog(touched); -} -void ARMAssemblerProxy::comment(const char* string) { - mTarget->comment(string); -} - - -void ARMAssemblerProxy::dataProcessing( int opcode, int cc, int s, - int Rd, int Rn, uint32_t Op2) -{ - mTarget->dataProcessing(opcode, cc, s, Rd, Rn, Op2); -} - -void ARMAssemblerProxy::MLA(int cc, int s, int Rd, int Rm, int Rs, int Rn) { - mTarget->MLA(cc, s, Rd, Rm, Rs, Rn); -} -void ARMAssemblerProxy::MUL(int cc, int s, int Rd, int Rm, int Rs) { - mTarget->MUL(cc, s, Rd, Rm, Rs); -} -void ARMAssemblerProxy::UMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - mTarget->UMULL(cc, s, RdLo, RdHi, Rm, Rs); -} -void ARMAssemblerProxy::UMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - mTarget->UMUAL(cc, s, RdLo, RdHi, Rm, Rs); -} -void ARMAssemblerProxy::SMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - mTarget->SMULL(cc, s, RdLo, RdHi, Rm, Rs); -} -void ARMAssemblerProxy::SMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs) { - mTarget->SMUAL(cc, s, RdLo, RdHi, Rm, Rs); -} - -void ARMAssemblerProxy::B(int cc, uint32_t* pc) { - mTarget->B(cc, pc); -} -void ARMAssemblerProxy::BL(int cc, uint32_t* pc) { - mTarget->BL(cc, pc); -} -void ARMAssemblerProxy::BX(int cc, int Rn) { - mTarget->BX(cc, Rn); -} -void ARMAssemblerProxy::label(const char* theLabel) { - mTarget->label(theLabel); -} -void ARMAssemblerProxy::B(int cc, const char* label) { - mTarget->B(cc, label); -} -void ARMAssemblerProxy::BL(int cc, const char* label) { - mTarget->BL(cc, label); -} - -uint32_t* ARMAssemblerProxy::pcForLabel(const char* label) { - return mTarget->pcForLabel(label); -} - -void ARMAssemblerProxy::LDR(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->LDR(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::LDRB(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->LDRB(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::STR(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->STR(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::STRB(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->STRB(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::LDRH(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->LDRH(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::LDRSB(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->LDRSB(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::LDRSH(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->LDRSH(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::STRH(int cc, int Rd, int Rn, uint32_t offset) { - mTarget->STRH(cc, Rd, Rn, offset); -} -void ARMAssemblerProxy::LDM(int cc, int dir, int Rn, int W, uint32_t reg_list) { - mTarget->LDM(cc, dir, Rn, W, reg_list); -} -void ARMAssemblerProxy::STM(int cc, int dir, int Rn, int W, uint32_t reg_list) { - mTarget->STM(cc, dir, Rn, W, reg_list); -} - -void ARMAssemblerProxy::SWP(int cc, int Rn, int Rd, int Rm) { - mTarget->SWP(cc, Rn, Rd, Rm); -} -void ARMAssemblerProxy::SWPB(int cc, int Rn, int Rd, int Rm) { - mTarget->SWPB(cc, Rn, Rd, Rm); -} -void ARMAssemblerProxy::SWI(int cc, uint32_t comment) { - mTarget->SWI(cc, comment); -} - - -void ARMAssemblerProxy::PLD(int Rn, uint32_t offset) { - mTarget->PLD(Rn, offset); -} -void ARMAssemblerProxy::CLZ(int cc, int Rd, int Rm) { - mTarget->CLZ(cc, Rd, Rm); -} -void ARMAssemblerProxy::QADD(int cc, int Rd, int Rm, int Rn) { - mTarget->QADD(cc, Rd, Rm, Rn); -} -void ARMAssemblerProxy::QDADD(int cc, int Rd, int Rm, int Rn) { - mTarget->QDADD(cc, Rd, Rm, Rn); -} -void ARMAssemblerProxy::QSUB(int cc, int Rd, int Rm, int Rn) { - mTarget->QSUB(cc, Rd, Rm, Rn); -} -void ARMAssemblerProxy::QDSUB(int cc, int Rd, int Rm, int Rn) { - mTarget->QDSUB(cc, Rd, Rm, Rn); -} -void ARMAssemblerProxy::SMUL(int cc, int xy, int Rd, int Rm, int Rs) { - mTarget->SMUL(cc, xy, Rd, Rm, Rs); -} -void ARMAssemblerProxy::SMULW(int cc, int y, int Rd, int Rm, int Rs) { - mTarget->SMULW(cc, y, Rd, Rm, Rs); -} -void ARMAssemblerProxy::SMLA(int cc, int xy, int Rd, int Rm, int Rs, int Rn) { - mTarget->SMLA(cc, xy, Rd, Rm, Rs, Rn); -} -void ARMAssemblerProxy::SMLAL( int cc, int xy, - int RdHi, int RdLo, int Rs, int Rm) { - mTarget->SMLAL(cc, xy, RdHi, RdLo, Rs, Rm); -} -void ARMAssemblerProxy::SMLAW(int cc, int y, int Rd, int Rm, int Rs, int Rn) { - mTarget->SMLAW(cc, y, Rd, Rm, Rs, Rn); -} - - -}; // namespace android - diff --git a/libpixelflinger/codeflinger/ARMAssemblerProxy.h b/libpixelflinger/codeflinger/ARMAssemblerProxy.h deleted file mode 100644 index 4bdca9cf5caca0c716094e6c22de0779496fc13f..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/ARMAssemblerProxy.h +++ /dev/null @@ -1,123 +0,0 @@ -/* libs/pixelflinger/codeflinger/ARMAssemblerProxy.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_ARMASSEMBLER_PROXY_H -#define ANDROID_ARMASSEMBLER_PROXY_H - -#include <stdint.h> -#include <sys/types.h> - -#include "codeflinger/ARMAssemblerInterface.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -class ARMAssemblerProxy : public ARMAssemblerInterface -{ -public: - // ARMAssemblerProxy take ownership of the target - - ARMAssemblerProxy(); - ARMAssemblerProxy(ARMAssemblerInterface* target); - virtual ~ARMAssemblerProxy(); - - void setTarget(ARMAssemblerInterface* target); - - virtual void reset(); - virtual int generate(const char* name); - virtual void disassemble(const char* name); - - virtual void prolog(); - virtual void epilog(uint32_t touched); - virtual void comment(const char* string); - - virtual void dataProcessing(int opcode, int cc, int s, - int Rd, int Rn, - uint32_t Op2); - virtual void MLA(int cc, int s, - int Rd, int Rm, int Rs, int Rn); - virtual void MUL(int cc, int s, - int Rd, int Rm, int Rs); - virtual void UMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void UMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void SMULL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - virtual void SMUAL(int cc, int s, - int RdLo, int RdHi, int Rm, int Rs); - - virtual void B(int cc, uint32_t* pc); - virtual void BL(int cc, uint32_t* pc); - virtual void BX(int cc, int Rn); - virtual void label(const char* theLabel); - virtual void B(int cc, const char* label); - virtual void BL(int cc, const char* label); - - uint32_t* pcForLabel(const char* label); - - virtual void LDR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void LDRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void STR (int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void STRB(int cc, int Rd, - int Rn, uint32_t offset = immed12_pre(0)); - virtual void LDRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDRSB(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDRSH(int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void STRH (int cc, int Rd, - int Rn, uint32_t offset = immed8_pre(0)); - virtual void LDM(int cc, int dir, - int Rn, int W, uint32_t reg_list); - virtual void STM(int cc, int dir, - int Rn, int W, uint32_t reg_list); - - virtual void SWP(int cc, int Rn, int Rd, int Rm); - virtual void SWPB(int cc, int Rn, int Rd, int Rm); - virtual void SWI(int cc, uint32_t comment); - - virtual void PLD(int Rn, uint32_t offset); - virtual void CLZ(int cc, int Rd, int Rm); - virtual void QADD(int cc, int Rd, int Rm, int Rn); - virtual void QDADD(int cc, int Rd, int Rm, int Rn); - virtual void QSUB(int cc, int Rd, int Rm, int Rn); - virtual void QDSUB(int cc, int Rd, int Rm, int Rn); - virtual void SMUL(int cc, int xy, - int Rd, int Rm, int Rs); - virtual void SMULW(int cc, int y, - int Rd, int Rm, int Rs); - virtual void SMLA(int cc, int xy, - int Rd, int Rm, int Rs, int Rn); - virtual void SMLAL(int cc, int xy, - int RdHi, int RdLo, int Rs, int Rm); - virtual void SMLAW(int cc, int y, - int Rd, int Rm, int Rs, int Rn); - -private: - ARMAssemblerInterface* mTarget; -}; - -}; // namespace android - -#endif //ANDROID_ARMASSEMBLER_PROXY_H diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp deleted file mode 100644 index 29410c8ab62c662f773ffea1ae2af655a0f0ffa4..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/CodeCache.cpp +++ /dev/null @@ -1,151 +0,0 @@ -/* libs/pixelflinger/codeflinger/CodeCache.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> - -#include <cutils/log.h> -#include <cutils/atomic.h> - -#include "codeflinger/CodeCache.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -#if defined(__arm__) -#include <unistd.h> -#include <errno.h> -#endif - -// ---------------------------------------------------------------------------- - -Assembly::Assembly(size_t size) - : mCount(1), mSize(0) -{ - mBase = (uint32_t*)malloc(size); - if (mBase) { - mSize = size; - } -} - -Assembly::~Assembly() -{ - free(mBase); -} - -void Assembly::incStrong(const void*) const -{ - android_atomic_inc(&mCount); -} - -void Assembly::decStrong(const void*) const -{ - if (android_atomic_dec(&mCount) == 1) { - delete this; - } -} - -ssize_t Assembly::size() const -{ - if (!mBase) return NO_MEMORY; - return mSize; -} - -uint32_t* Assembly::base() const -{ - return mBase; -} - -ssize_t Assembly::resize(size_t newSize) -{ - mBase = (uint32_t*)realloc(mBase, newSize); - mSize = newSize; - return size(); -} - -// ---------------------------------------------------------------------------- - -CodeCache::CodeCache(size_t size) - : mCacheSize(size), mCacheInUse(0) -{ - pthread_mutex_init(&mLock, 0); -} - -CodeCache::~CodeCache() -{ - pthread_mutex_destroy(&mLock); -} - -sp<Assembly> CodeCache::lookup(const AssemblyKeyBase& keyBase) const -{ - pthread_mutex_lock(&mLock); - sp<Assembly> r; - ssize_t index = mCacheData.indexOfKey(key_t(keyBase)); - if (index >= 0) { - const cache_entry_t& e = mCacheData.valueAt(index); - e.when = mWhen++; - r = e.entry; - } - pthread_mutex_unlock(&mLock); - return r; -} - -int CodeCache::cache( const AssemblyKeyBase& keyBase, - const sp<Assembly>& assembly) -{ - pthread_mutex_lock(&mLock); - - const ssize_t assemblySize = assembly->size(); - while (mCacheInUse + assemblySize > mCacheSize) { - // evict the LRU - size_t lru = 0; - size_t count = mCacheData.size(); - for (size_t i=0 ; i<count ; i++) { - const cache_entry_t& e = mCacheData.valueAt(i); - if (e.when < mCacheData.valueAt(lru).when) { - lru = i; - } - } - const cache_entry_t& e = mCacheData.valueAt(lru); - mCacheInUse -= e.entry->size(); - mCacheData.removeItemsAt(lru); - } - - ssize_t err = mCacheData.add(key_t(keyBase), cache_entry_t(assembly, mWhen)); - if (err >= 0) { - mCacheInUse += assemblySize; - mWhen++; - // synchronize caches... -#if defined(__arm__) - const long base = long(assembly->base()); - const long curr = base + long(assembly->size()); - err = cacheflush(base, curr, 0); - LOGE_IF(err, "__ARM_NR_cacheflush error %s\n", - strerror(errno)); -#endif - } - - pthread_mutex_unlock(&mLock); - return err; -} - -// ---------------------------------------------------------------------------- - -}; // namespace android diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h deleted file mode 100644 index 370ce175ef6f16200915ac65db23131af4c2d1a8..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/CodeCache.h +++ /dev/null @@ -1,134 +0,0 @@ -/* libs/pixelflinger/codeflinger/CodeCache.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_CODECACHE_H -#define ANDROID_CODECACHE_H - -#include <stdint.h> -#include <pthread.h> -#include <sys/types.h> - -#include <utils/KeyedVector.h> - -#include "tinyutils/smartpointer.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -class AssemblyKeyBase { -public: - virtual ~AssemblyKeyBase() { } - virtual int compare_type(const AssemblyKeyBase& key) const = 0; -}; - -template <typename T> -class AssemblyKey : public AssemblyKeyBase -{ -public: - AssemblyKey(const T& rhs) : mKey(rhs) { } - virtual int compare_type(const AssemblyKeyBase& key) const { - const T& rhs = static_cast<const AssemblyKey&>(key).mKey; - return android::compare_type(mKey, rhs); - } -private: - T mKey; -}; - -// ---------------------------------------------------------------------------- - -class Assembly -{ -public: - Assembly(size_t size); - virtual ~Assembly(); - - ssize_t size() const; - uint32_t* base() const; - ssize_t resize(size_t size); - - // protocol for sp<> - void incStrong(const void* id) const; - void decStrong(const void* id) const; - typedef void weakref_type; - -private: - mutable int32_t mCount; - uint32_t* mBase; - ssize_t mSize; -}; - -// ---------------------------------------------------------------------------- - -class CodeCache -{ -public: -// pretty simple cache API... - CodeCache(size_t size); - ~CodeCache(); - - sp<Assembly> lookup(const AssemblyKeyBase& key) const; - - int cache( const AssemblyKeyBase& key, - const sp<Assembly>& assembly); - -private: - // nothing to see here... - struct cache_entry_t { - inline cache_entry_t() { } - inline cache_entry_t(const sp<Assembly>& a, int64_t w) - : entry(a), when(w) { } - sp<Assembly> entry; - mutable int64_t when; - }; - - class key_t { - friend int compare_type( - const key_value_pair_t<key_t, cache_entry_t>&, - const key_value_pair_t<key_t, cache_entry_t>&); - const AssemblyKeyBase* mKey; - public: - key_t() { }; - key_t(const AssemblyKeyBase& k) : mKey(&k) { } - }; - - mutable pthread_mutex_t mLock; - mutable int64_t mWhen; - size_t mCacheSize; - size_t mCacheInUse; - KeyedVector<key_t, cache_entry_t> mCacheData; - - friend int compare_type( - const key_value_pair_t<key_t, cache_entry_t>&, - const key_value_pair_t<key_t, cache_entry_t>&); -}; - -// KeyedVector uses compare_type(), which is more efficient, than -// just using operator < () -inline int compare_type( - const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& lhs, - const key_value_pair_t<CodeCache::key_t, CodeCache::cache_entry_t>& rhs) -{ - return lhs.key.mKey->compare_type(*(rhs.key.mKey)); -} - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif //ANDROID_CODECACHE_H diff --git a/libpixelflinger/codeflinger/GGLAssembler.cpp b/libpixelflinger/codeflinger/GGLAssembler.cpp deleted file mode 100644 index 1cd189c9f7057ffa9b7088771bd1426bcb234149..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/GGLAssembler.cpp +++ /dev/null @@ -1,1150 +0,0 @@ -/* libs/pixelflinger/codeflinger/GGLAssembler.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#define LOG_TAG "GGLAssembler" - -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> -#include <cutils/log.h> - -#include "codeflinger/GGLAssembler.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -GGLAssembler::GGLAssembler(ARMAssemblerInterface* target) - : ARMAssemblerProxy(target), RegisterAllocator(), mOptLevel(7) -{ -} - -GGLAssembler::~GGLAssembler() -{ -} - -void GGLAssembler::prolog() -{ - ARMAssemblerProxy::prolog(); -} - -void GGLAssembler::epilog(uint32_t touched) -{ - ARMAssemblerProxy::epilog(touched); -} - -void GGLAssembler::reset(int opt_level) -{ - ARMAssemblerProxy::reset(); - RegisterAllocator::reset(); - mOptLevel = opt_level; -} - -// --------------------------------------------------------------------------- - -int GGLAssembler::scanline(const needs_t& needs, context_t const* c) -{ - int err = 0; - int opt_level = mOptLevel; - while (opt_level >= 0) { - reset(opt_level); - err = scanline_core(needs, c); - if (err == 0) - break; - opt_level--; - } - - // XXX: in theory, pcForLabel is not valid before generate() - uint32_t* fragment_start_pc = pcForLabel("fragment_loop"); - uint32_t* fragment_end_pc = pcForLabel("epilog"); - const int per_fragment_ops = int(fragment_end_pc - fragment_start_pc); - - // build a name for our pipeline - char name[64]; - sprintf(name, - "scanline__%08X:%08X_%08X_%08X [%3d ipp]", - needs.p, needs.n, needs.t[0], needs.t[1], per_fragment_ops); - - if (err) { - LOGE("Error while generating ""%s""\n", name); - disassemble(name); - return -1; - } - - return generate(name); -} - -int GGLAssembler::scanline_core(const needs_t& needs, context_t const* c) -{ - int64_t duration = ggl_system_time(); - - mBlendFactorCached = 0; - mBlending = 0; - mMasking = 0; - mAA = GGL_READ_NEEDS(P_AA, needs.p); - mDithering = GGL_READ_NEEDS(P_DITHER, needs.p); - mAlphaTest = GGL_READ_NEEDS(P_ALPHA_TEST, needs.p) + GGL_NEVER; - mDepthTest = GGL_READ_NEEDS(P_DEPTH_TEST, needs.p) + GGL_NEVER; - mFog = GGL_READ_NEEDS(P_FOG, needs.p) != 0; - mSmooth = GGL_READ_NEEDS(SHADE, needs.n) != 0; - mBuilderContext.needs = needs; - mBuilderContext.c = c; - mBuilderContext.Rctx = reserveReg(R0); // context always in R0 - mCbFormat = c->formats[ GGL_READ_NEEDS(CB_FORMAT, needs.n) ]; - - // ------------------------------------------------------------------------ - - decodeLogicOpNeeds(needs); - - decodeTMUNeeds(needs, c); - - mBlendSrc = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_SRC, needs.n)); - mBlendDst = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_DST, needs.n)); - mBlendSrcA = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_SRCA, needs.n)); - mBlendDstA = ggl_needs_to_blendfactor(GGL_READ_NEEDS(BLEND_DSTA, needs.n)); - - if (!mCbFormat.c[GGLFormat::ALPHA].h) { - if ((mBlendSrc == GGL_ONE_MINUS_DST_ALPHA) || - (mBlendSrc == GGL_DST_ALPHA)) { - mBlendSrc = GGL_ONE; - } - if ((mBlendSrcA == GGL_ONE_MINUS_DST_ALPHA) || - (mBlendSrcA == GGL_DST_ALPHA)) { - mBlendSrcA = GGL_ONE; - } - if ((mBlendDst == GGL_ONE_MINUS_DST_ALPHA) || - (mBlendDst == GGL_DST_ALPHA)) { - mBlendDst = GGL_ONE; - } - if ((mBlendDstA == GGL_ONE_MINUS_DST_ALPHA) || - (mBlendDstA == GGL_DST_ALPHA)) { - mBlendDstA = GGL_ONE; - } - } - - // if we need the framebuffer, read it now - const int blending = blending_codes(mBlendSrc, mBlendDst) | - blending_codes(mBlendSrcA, mBlendDstA); - - // XXX: handle special cases, destination not modified... - if ((mBlendSrc==GGL_ZERO) && (mBlendSrcA==GGL_ZERO) && - (mBlendDst==GGL_ONE) && (mBlendDstA==GGL_ONE)) { - // Destination unmodified (beware of logic ops) - } else if ((mBlendSrc==GGL_ZERO) && (mBlendSrcA==GGL_ZERO) && - (mBlendDst==GGL_ZERO) && (mBlendDstA==GGL_ZERO)) { - // Destination is zero (beware of logic ops) - } - - int fbComponents = 0; - const int masking = GGL_READ_NEEDS(MASK_ARGB, needs.n); - for (int i=0 ; i<4 ; i++) { - const int mask = 1<<i; - component_info_t& info = mInfo[i]; - int fs = i==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc; - int fd = i==GGLFormat::ALPHA ? mBlendDstA : mBlendDst; - if (fs==GGL_SRC_ALPHA_SATURATE && i==GGLFormat::ALPHA) - fs = GGL_ONE; - info.masked = !!(masking & mask); - info.inDest = !info.masked && mCbFormat.c[i].h && - ((mLogicOp & LOGIC_OP_SRC) || (!mLogicOp)); - if (mCbFormat.components >= GGL_LUMINANCE && - (i==GGLFormat::GREEN || i==GGLFormat::BLUE)) { - info.inDest = false; - } - info.needed = (i==GGLFormat::ALPHA) && - (isAlphaSourceNeeded() || mAlphaTest != GGL_ALWAYS); - info.replaced = !!(mTextureMachine.replaced & mask); - info.iterated = (!info.replaced && (info.inDest || info.needed)); - info.smooth = mSmooth && info.iterated; - info.fog = mFog && info.inDest && (i != GGLFormat::ALPHA); - info.blend = (fs != int(GGL_ONE)) || (fd > int(GGL_ZERO)); - - mBlending |= (info.blend ? mask : 0); - mMasking |= (mCbFormat.c[i].h && info.masked) ? mask : 0; - fbComponents |= mCbFormat.c[i].h ? mask : 0; - } - - mAllMasked = (mMasking == fbComponents); - if (mAllMasked) { - mDithering = 0; - } - - fragment_parts_t parts; - - // ------------------------------------------------------------------------ - prolog(); - // ------------------------------------------------------------------------ - - build_scanline_prolog(parts, needs); - - if (registerFile().status()) - return registerFile().status(); - - // ------------------------------------------------------------------------ - label("fragment_loop"); - // ------------------------------------------------------------------------ - { - Scratch regs(registerFile()); - - if (mDithering) { - // update the dither index. - MOV(AL, 0, parts.count.reg, - reg_imm(parts.count.reg, ROR, GGL_DITHER_ORDER_SHIFT)); - ADD(AL, 0, parts.count.reg, parts.count.reg, - imm( 1 << (32 - GGL_DITHER_ORDER_SHIFT))); - MOV(AL, 0, parts.count.reg, - reg_imm(parts.count.reg, ROR, 32 - GGL_DITHER_ORDER_SHIFT)); - } - - // XXX: could we do an early alpha-test here in some cases? - // It would probaly be used only with smooth-alpha and no texture - // (or no alpha component in the texture). - - // Early z-test - if (mAlphaTest==GGL_ALWAYS) { - build_depth_test(parts, Z_TEST|Z_WRITE); - } else { - // we cannot do the z-write here, because - // it might be killed by the alpha-test later - build_depth_test(parts, Z_TEST); - } - - { // texture coordinates - Scratch scratches(registerFile()); - - // texel generation - build_textures(parts, regs); - } - - if ((blending & (FACTOR_DST|BLEND_DST)) || - (mMasking && !mAllMasked) || - (mLogicOp & LOGIC_OP_DST)) - { - // blending / logic_op / masking need the framebuffer - mDstPixel.setTo(regs.obtain(), &mCbFormat); - - // load the framebuffer pixel - comment("fetch color-buffer"); - load(parts.cbPtr, mDstPixel); - } - - if (registerFile().status()) - return registerFile().status(); - - pixel_t pixel; - int directTex = mTextureMachine.directTexture; - if (directTex | parts.packed) { - // note: we can't have both here - // iterated color or direct texture - pixel = directTex ? parts.texel[directTex-1] : parts.iterated; - pixel.flags &= ~CORRUPTIBLE; - } else { - if (mDithering) { - const int ctxtReg = mBuilderContext.Rctx; - const int mask = GGL_DITHER_SIZE-1; - parts.dither = reg_t(regs.obtain()); - AND(AL, 0, parts.dither.reg, parts.count.reg, imm(mask)); - ADD(AL, 0, parts.dither.reg, parts.dither.reg, ctxtReg); - LDRB(AL, parts.dither.reg, parts.dither.reg, - immed12_pre(GGL_OFFSETOF(ditherMatrix))); - } - - // allocate a register for the resulting pixel - pixel.setTo(regs.obtain(), &mCbFormat, FIRST); - - build_component(pixel, parts, GGLFormat::ALPHA, regs); - - if (mAlphaTest!=GGL_ALWAYS) { - // only handle the z-write part here. We know z-test - // was successful, as well as alpha-test. - build_depth_test(parts, Z_WRITE); - } - - build_component(pixel, parts, GGLFormat::RED, regs); - build_component(pixel, parts, GGLFormat::GREEN, regs); - build_component(pixel, parts, GGLFormat::BLUE, regs); - - pixel.flags |= CORRUPTIBLE; - } - - if (registerFile().status()) - return registerFile().status(); - - if (pixel.reg == -1) { - // be defensive here. if we're here it's probably - // that this whole fragment is a no-op. - pixel = mDstPixel; - } - - if (!mAllMasked) { - // logic operation - build_logic_op(pixel, regs); - - // masking - build_masking(pixel, regs); - - comment("store"); - store(parts.cbPtr, pixel, WRITE_BACK); - } - } - - if (registerFile().status()) - return registerFile().status(); - - // update the iterated color... - if (parts.reload != 3) { - build_smooth_shade(parts); - } - - // update iterated z - build_iterate_z(parts); - - // update iterated fog - build_iterate_f(parts); - - SUB(AL, S, parts.count.reg, parts.count.reg, imm(1<<16)); - B(PL, "fragment_loop"); - label("epilog"); - epilog(registerFile().touched()); - - if ((mAlphaTest!=GGL_ALWAYS) || (mDepthTest!=GGL_ALWAYS)) { - if (mDepthTest!=GGL_ALWAYS) { - label("discard_before_textures"); - build_iterate_texture_coordinates(parts); - } - label("discard_after_textures"); - build_smooth_shade(parts); - build_iterate_z(parts); - build_iterate_f(parts); - if (!mAllMasked) { - ADD(AL, 0, parts.cbPtr.reg, parts.cbPtr.reg, imm(parts.cbPtr.size>>3)); - } - SUB(AL, S, parts.count.reg, parts.count.reg, imm(1<<16)); - B(PL, "fragment_loop"); - epilog(registerFile().touched()); - } - - return registerFile().status(); -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_scanline_prolog( - fragment_parts_t& parts, const needs_t& needs) -{ - Scratch scratches(registerFile()); - int Rctx = mBuilderContext.Rctx; - - // compute count - comment("compute ct (# of pixels to process)"); - parts.count.setTo(obtainReg()); - int Rx = scratches.obtain(); - int Ry = scratches.obtain(); - CONTEXT_LOAD(Rx, iterators.xl); - CONTEXT_LOAD(parts.count.reg, iterators.xr); - CONTEXT_LOAD(Ry, iterators.y); - - // parts.count = iterators.xr - Rx - SUB(AL, 0, parts.count.reg, parts.count.reg, Rx); - SUB(AL, 0, parts.count.reg, parts.count.reg, imm(1)); - - if (mDithering) { - // parts.count.reg = 0xNNNNXXDD - // NNNN = count-1 - // DD = dither offset - // XX = 0xxxxxxx (x = garbage) - Scratch scratches(registerFile()); - int tx = scratches.obtain(); - int ty = scratches.obtain(); - AND(AL, 0, tx, Rx, imm(GGL_DITHER_MASK)); - AND(AL, 0, ty, Ry, imm(GGL_DITHER_MASK)); - ADD(AL, 0, tx, tx, reg_imm(ty, LSL, GGL_DITHER_ORDER_SHIFT)); - ORR(AL, 0, parts.count.reg, tx, reg_imm(parts.count.reg, LSL, 16)); - } else { - // parts.count.reg = 0xNNNN0000 - // NNNN = count-1 - MOV(AL, 0, parts.count.reg, reg_imm(parts.count.reg, LSL, 16)); - } - - if (!mAllMasked) { - // compute dst ptr - comment("compute color-buffer pointer"); - const int cb_bits = mCbFormat.size*8; - int Rs = scratches.obtain(); - parts.cbPtr.setTo(obtainReg(), cb_bits); - CONTEXT_LOAD(Rs, state.buffers.color.stride); - CONTEXT_LOAD(parts.cbPtr.reg, state.buffers.color.data); - SMLABB(AL, Rs, Ry, Rs, Rx); // Rs = Rx + Ry*Rs - base_offset(parts.cbPtr, parts.cbPtr, Rs); - scratches.recycle(Rs); - } - - // init fog - const int need_fog = GGL_READ_NEEDS(P_FOG, needs.p); - if (need_fog) { - comment("compute initial fog coordinate"); - Scratch scratches(registerFile()); - int dfdx = scratches.obtain(); - int ydfdy = scratches.obtain(); - int f = ydfdy; - CONTEXT_LOAD(dfdx, generated_vars.dfdx); - CONTEXT_LOAD(ydfdy, iterators.ydfdy); - MLA(AL, 0, f, Rx, dfdx, ydfdy); - CONTEXT_STORE(f, generated_vars.f); - } - - // init Z coordinate - if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) { - parts.z = reg_t(obtainReg()); - comment("compute initial Z coordinate"); - Scratch scratches(registerFile()); - int dzdx = scratches.obtain(); - int ydzdy = parts.z.reg; - CONTEXT_LOAD(dzdx, generated_vars.dzdx); // 1.31 fixed-point - CONTEXT_LOAD(ydzdy, iterators.ydzdy); // 1.31 fixed-point - MLA(AL, 0, parts.z.reg, Rx, dzdx, ydzdy); - - // we're going to index zbase of parts.count - // zbase = base + (xl-count + stride*y)*2 - int Rs = dzdx; - int zbase = scratches.obtain(); - CONTEXT_LOAD(Rs, state.buffers.depth.stride); - CONTEXT_LOAD(zbase, state.buffers.depth.data); - SMLABB(AL, Rs, Ry, Rs, Rx); - ADD(AL, 0, Rs, Rs, reg_imm(parts.count.reg, LSR, 16)); - ADD(AL, 0, zbase, zbase, reg_imm(Rs, LSL, 1)); - CONTEXT_STORE(zbase, generated_vars.zbase); - } - - // init texture coordinates - init_textures(parts.coords, reg_t(Rx), reg_t(Ry)); - scratches.recycle(Ry); - - // iterated color - init_iterated_color(parts, reg_t(Rx)); - - // init coverage factor application (anti-aliasing) - if (mAA) { - parts.covPtr.setTo(obtainReg(), 16); - CONTEXT_LOAD(parts.covPtr.reg, state.buffers.coverage); - ADD(AL, 0, parts.covPtr.reg, parts.covPtr.reg, reg_imm(Rx, LSL, 1)); - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_component( pixel_t& pixel, - const fragment_parts_t& parts, - int component, - Scratch& regs) -{ - static char const * comments[] = {"alpha", "red", "green", "blue"}; - comment(comments[component]); - - // local register file - Scratch scratches(registerFile()); - const int dst_component_size = pixel.component_size(component); - - component_t temp(-1); - build_incoming_component( temp, dst_component_size, - parts, component, scratches, regs); - - if (mInfo[component].inDest) { - - // blending... - build_blending( temp, mDstPixel, component, scratches ); - - // downshift component and rebuild pixel... - downshift(pixel, component, temp, parts.dither); - } -} - -void GGLAssembler::build_incoming_component( - component_t& temp, - int dst_size, - const fragment_parts_t& parts, - int component, - Scratch& scratches, - Scratch& global_regs) -{ - const uint32_t component_mask = 1<<component; - - // Figure out what we need for the blending stage... - int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc; - int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst; - if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA) { - fs = GGL_ONE; - } - - // Figure out what we need to extract and for what reason - const int blending = blending_codes(fs, fd); - - // Are we actually going to blend? - const int need_blending = (fs != int(GGL_ONE)) || (fd > int(GGL_ZERO)); - - // expand the source if the destination has more bits - int need_expander = false; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT-1 ; i++) { - texture_unit_t& tmu = mTextureMachine.tmu[i]; - if ((tmu.format_idx) && - (parts.texel[i].component_size(component) < dst_size)) { - need_expander = true; - } - } - - // do we need to extract this component? - const bool multiTexture = mTextureMachine.activeUnits > 1; - const int blend_needs_alpha_source = (component==GGLFormat::ALPHA) && - (isAlphaSourceNeeded()); - int need_extract = mInfo[component].needed; - if (mInfo[component].inDest) - { - need_extract |= ((need_blending ? - (blending & (BLEND_SRC|FACTOR_SRC)) : need_expander)); - need_extract |= (mTextureMachine.mask != mTextureMachine.replaced); - need_extract |= mInfo[component].smooth; - need_extract |= mInfo[component].fog; - need_extract |= mDithering; - need_extract |= multiTexture; - } - - if (need_extract) { - Scratch& regs = blend_needs_alpha_source ? global_regs : scratches; - component_t fragment; - - // iterated color - build_iterated_color(fragment, parts, component, regs); - - // texture environement (decal, modulate, replace) - build_texture_environment(fragment, parts, component, regs); - - // expand the source if the destination has more bits - if (need_expander && (fragment.size() < dst_size)) { - // we're here only if we fetched a texel - // (so we know for sure fragment is CORRUPTIBLE) - expand(fragment, fragment, dst_size); - } - - // We have a few specific things to do for the alpha-channel - if ((component==GGLFormat::ALPHA) && - (mInfo[component].needed || fragment.size()<dst_size)) - { - // convert to integer_t first and make sure - // we don't corrupt a needed register - if (fragment.l) { - component_t incoming(fragment); - modify(fragment, regs); - MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSR, incoming.l)); - fragment.h -= fragment.l; - fragment.l = 0; - } - - // coverage factor application - build_coverage_application(fragment, parts, regs); - - // alpha-test - build_alpha_test(fragment, parts); - - if (blend_needs_alpha_source) { - // We keep only 8 bits for the blending stage - const int shift = fragment.h <= 8 ? 0 : fragment.h-8; - if (fragment.flags & CORRUPTIBLE) { - fragment.flags &= ~CORRUPTIBLE; - mAlphaSource.setTo(fragment.reg, - fragment.size(), fragment.flags); - if (shift) { - MOV(AL, 0, mAlphaSource.reg, - reg_imm(mAlphaSource.reg, LSR, shift)); - } - } else { - // XXX: it would better to do this in build_blend_factor() - // so we can avoid the extra MOV below. - mAlphaSource.setTo(regs.obtain(), - fragment.size(), CORRUPTIBLE); - if (shift) { - MOV(AL, 0, mAlphaSource.reg, - reg_imm(fragment.reg, LSR, shift)); - } else { - MOV(AL, 0, mAlphaSource.reg, fragment.reg); - } - } - mAlphaSource.s -= shift; - } - } - - // fog... - build_fog( fragment, component, regs ); - - temp = fragment; - } else { - if (mInfo[component].inDest) { - // extraction not needed and replace - // we just select the right component - if ((mTextureMachine.replaced & component_mask) == 0) { - // component wasn't replaced, so use it! - temp = component_t(parts.iterated, component); - } - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { - const texture_unit_t& tmu = mTextureMachine.tmu[i]; - if ((tmu.mask & component_mask) && - ((tmu.replaced & component_mask) == 0)) { - temp = component_t(parts.texel[i], component); - } - } - } - } -} - -bool GGLAssembler::isAlphaSourceNeeded() const -{ - // XXX: also needed for alpha-test - const int bs = mBlendSrc; - const int bd = mBlendDst; - return bs==GGL_SRC_ALPHA_SATURATE || - bs==GGL_SRC_ALPHA || bs==GGL_ONE_MINUS_SRC_ALPHA || - bd==GGL_SRC_ALPHA || bd==GGL_ONE_MINUS_SRC_ALPHA ; -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_smooth_shade(const fragment_parts_t& parts) -{ - if (mSmooth && !parts.iterated_packed) { - // update the iterated color in a pipelined way... - comment("update iterated color"); - Scratch scratches(registerFile()); - - const int reload = parts.reload; - for (int i=0 ; i<4 ; i++) { - if (!mInfo[i].iterated) - continue; - - int c = parts.argb[i].reg; - int dx = parts.argb_dx[i].reg; - - if (reload & 1) { - c = scratches.obtain(); - CONTEXT_LOAD(c, generated_vars.argb[i].c); - } - if (reload & 2) { - dx = scratches.obtain(); - CONTEXT_LOAD(dx, generated_vars.argb[i].dx); - } - - if (mSmooth) { - ADD(AL, 0, c, c, dx); - } - - if (reload & 1) { - CONTEXT_STORE(c, generated_vars.argb[i].c); - scratches.recycle(c); - } - if (reload & 2) { - scratches.recycle(dx); - } - } - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_coverage_application(component_t& fragment, - const fragment_parts_t& parts, Scratch& regs) -{ - // here fragment.l is guarenteed to be 0 - if (mAA) { - // coverages are 1.15 fixed-point numbers - comment("coverage application"); - - component_t incoming(fragment); - modify(fragment, regs); - - Scratch scratches(registerFile()); - int cf = scratches.obtain(); - LDRH(AL, cf, parts.covPtr.reg, immed8_post(2)); - if (fragment.h > 31) { - fragment.h--; - SMULWB(AL, fragment.reg, incoming.reg, cf); - } else { - MOV(AL, 0, fragment.reg, reg_imm(incoming.reg, LSL, 1)); - SMULWB(AL, fragment.reg, fragment.reg, cf); - } - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_alpha_test(component_t& fragment, - const fragment_parts_t& parts) -{ - if (mAlphaTest != GGL_ALWAYS) { - comment("Alpha Test"); - Scratch scratches(registerFile()); - int ref = scratches.obtain(); - const int shift = GGL_COLOR_BITS-fragment.size(); - CONTEXT_LOAD(ref, state.alpha_test.ref); - if (shift) CMP(AL, fragment.reg, reg_imm(ref, LSR, shift)); - else CMP(AL, fragment.reg, ref); - int cc = NV; - switch (mAlphaTest) { - case GGL_NEVER: cc = NV; break; - case GGL_LESS: cc = LT; break; - case GGL_EQUAL: cc = EQ; break; - case GGL_LEQUAL: cc = LS; break; - case GGL_GREATER: cc = HI; break; - case GGL_NOTEQUAL: cc = NE; break; - case GGL_GEQUAL: cc = HS; break; - } - B(cc^1, "discard_after_textures"); - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_depth_test( - const fragment_parts_t& parts, uint32_t mask) -{ - mask &= Z_TEST|Z_WRITE; - const needs_t& needs = mBuilderContext.needs; - const int zmask = GGL_READ_NEEDS(P_MASK_Z, needs.p); - Scratch scratches(registerFile()); - - if (mDepthTest != GGL_ALWAYS || zmask) { - int cc=AL, ic=AL; - switch (mDepthTest) { - case GGL_LESS: ic = HI; break; - case GGL_EQUAL: ic = EQ; break; - case GGL_LEQUAL: ic = HS; break; - case GGL_GREATER: ic = LT; break; - case GGL_NOTEQUAL: ic = NE; break; - case GGL_GEQUAL: ic = LS; break; - case GGL_NEVER: - // this never happens, because it's taken care of when - // computing the needs. but we keep it for completness. - comment("Depth Test (NEVER)"); - B(AL, "discard_before_textures"); - return; - case GGL_ALWAYS: - // we're here because zmask is enabled - mask &= ~Z_TEST; // test always passes. - break; - } - - // inverse the condition - cc = ic^1; - - if ((mask & Z_WRITE) && !zmask) { - mask &= ~Z_WRITE; - } - - if (!mask) - return; - - comment("Depth Test"); - - int zbase = scratches.obtain(); - int depth = scratches.obtain(); - int z = parts.z.reg; - - CONTEXT_LOAD(zbase, generated_vars.zbase); // stall - SUB(AL, 0, zbase, zbase, reg_imm(parts.count.reg, LSR, 15)); - // above does zbase = zbase + ((count >> 16) << 1) - - if (mask & Z_TEST) { - LDRH(AL, depth, zbase); // stall - CMP(AL, depth, reg_imm(z, LSR, 16)); - B(cc, "discard_before_textures"); - } - if (mask & Z_WRITE) { - if (mask == Z_WRITE) { - // only z-write asked, cc is meaningless - ic = AL; - } - MOV(AL, 0, depth, reg_imm(z, LSR, 16)); - STRH(ic, depth, zbase); - } - } -} - -void GGLAssembler::build_iterate_z(const fragment_parts_t& parts) -{ - const needs_t& needs = mBuilderContext.needs; - if ((mDepthTest != GGL_ALWAYS) || GGL_READ_NEEDS(P_MASK_Z, needs.p)) { - Scratch scratches(registerFile()); - int dzdx = scratches.obtain(); - CONTEXT_LOAD(dzdx, generated_vars.dzdx); // stall - ADD(AL, 0, parts.z.reg, parts.z.reg, dzdx); - } -} - -void GGLAssembler::build_iterate_f(const fragment_parts_t& parts) -{ - const needs_t& needs = mBuilderContext.needs; - if (GGL_READ_NEEDS(P_FOG, needs.p)) { - Scratch scratches(registerFile()); - int dfdx = scratches.obtain(); - int f = scratches.obtain(); - CONTEXT_LOAD(f, generated_vars.f); - CONTEXT_LOAD(dfdx, generated_vars.dfdx); // stall - ADD(AL, 0, f, f, dfdx); - CONTEXT_STORE(f, generated_vars.f); - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_logic_op(pixel_t& pixel, Scratch& regs) -{ - const needs_t& needs = mBuilderContext.needs; - const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR; - if (opcode == GGL_COPY) - return; - - comment("logic operation"); - - pixel_t s(pixel); - if (!(pixel.flags & CORRUPTIBLE)) { - pixel.reg = regs.obtain(); - pixel.flags |= CORRUPTIBLE; - } - - pixel_t d(mDstPixel); - switch(opcode) { - case GGL_CLEAR: MOV(AL, 0, pixel.reg, imm(0)); break; - case GGL_AND: AND(AL, 0, pixel.reg, s.reg, d.reg); break; - case GGL_AND_REVERSE: BIC(AL, 0, pixel.reg, s.reg, d.reg); break; - case GGL_COPY: break; - case GGL_AND_INVERTED: BIC(AL, 0, pixel.reg, d.reg, s.reg); break; - case GGL_NOOP: MOV(AL, 0, pixel.reg, d.reg); break; - case GGL_XOR: EOR(AL, 0, pixel.reg, s.reg, d.reg); break; - case GGL_OR: ORR(AL, 0, pixel.reg, s.reg, d.reg); break; - case GGL_NOR: ORR(AL, 0, pixel.reg, s.reg, d.reg); - MVN(AL, 0, pixel.reg, pixel.reg); break; - case GGL_EQUIV: EOR(AL, 0, pixel.reg, s.reg, d.reg); - MVN(AL, 0, pixel.reg, pixel.reg); break; - case GGL_INVERT: MVN(AL, 0, pixel.reg, d.reg); break; - case GGL_OR_REVERSE: // s | ~d == ~(~s & d) - BIC(AL, 0, pixel.reg, d.reg, s.reg); - MVN(AL, 0, pixel.reg, pixel.reg); break; - case GGL_COPY_INVERTED: MVN(AL, 0, pixel.reg, s.reg); break; - case GGL_OR_INVERTED: // ~s | d == ~(s & ~d) - BIC(AL, 0, pixel.reg, s.reg, d.reg); - MVN(AL, 0, pixel.reg, pixel.reg); break; - case GGL_NAND: AND(AL, 0, pixel.reg, s.reg, d.reg); - MVN(AL, 0, pixel.reg, pixel.reg); break; - case GGL_SET: MVN(AL, 0, pixel.reg, imm(0)); break; - }; -} - -// --------------------------------------------------------------------------- - -static uint32_t find_bottom(uint32_t val) -{ - uint32_t i = 0; - while (!(val & (3<<i))) - i+= 2; - return i; -} - -static void normalize(uint32_t& val, uint32_t& rot) -{ - rot = 0; - while (!(val&3) || (val & 0xFC000000)) { - uint32_t newval; - newval = val >> 2; - newval |= (val&3) << 30; - val = newval; - rot += 2; - if (rot == 32) { - rot = 0; - break; - } - } -} - -void GGLAssembler::build_and_immediate(int d, int s, uint32_t mask, int bits) -{ - uint32_t rot; - uint32_t size = ((bits>=32) ? 0 : (1LU << bits)) - 1; - mask &= size; - - if (mask == size) { - if (d != s) - MOV( AL, 0, d, s); - return; - } - - int negative_logic = !isValidImmediate(mask); - if (negative_logic) { - mask = ~mask & size; - } - normalize(mask, rot); - - if (mask) { - while (mask) { - uint32_t bitpos = find_bottom(mask); - int shift = rot + bitpos; - uint32_t m = mask & (0xff << bitpos); - mask &= ~m; - m >>= bitpos; - int32_t newMask = (m<<shift) | (m>>(32-shift)); - if (!negative_logic) { - AND( AL, 0, d, s, imm(newMask) ); - } else { - BIC( AL, 0, d, s, imm(newMask) ); - } - s = d; - } - } else { - MOV( AL, 0, d, imm(0)); - } -} - -void GGLAssembler::build_masking(pixel_t& pixel, Scratch& regs) -{ - if (!mMasking || mAllMasked) { - return; - } - - comment("color mask"); - - pixel_t fb(mDstPixel); - pixel_t s(pixel); - if (!(pixel.flags & CORRUPTIBLE)) { - pixel.reg = regs.obtain(); - pixel.flags |= CORRUPTIBLE; - } - - int mask = 0; - for (int i=0 ; i<4 ; i++) { - const int component_mask = 1<<i; - const int h = fb.format.c[i].h; - const int l = fb.format.c[i].l; - if (h && (!(mMasking & component_mask))) { - mask |= ((1<<(h-l))-1) << l; - } - } - - // There is no need to clear the masked components of the source - // (unless we applied a logic op), because they're already zeroed - // by construction (masked components are not computed) - - if (mLogicOp) { - const needs_t& needs = mBuilderContext.needs; - const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR; - if (opcode != GGL_CLEAR) { - // clear masked component of source - build_and_immediate(pixel.reg, s.reg, mask, fb.size()); - s = pixel; - } - } - - // clear non masked components of destination - build_and_immediate(fb.reg, fb.reg, ~mask, fb.size()); - - // or back the channels that were masked - if (s.reg == fb.reg) { - // this is in fact a MOV - if (s.reg == pixel.reg) { - // ugh. this in in fact a nop - } else { - MOV(AL, 0, pixel.reg, fb.reg); - } - } else { - ORR(AL, 0, pixel.reg, s.reg, fb.reg); - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::base_offset( - const pointer_t& d, const pointer_t& b, const reg_t& o) -{ - switch (b.size) { - case 32: - ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 2)); - break; - case 24: - if (d.reg == b.reg) { - ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1)); - ADD(AL, 0, d.reg, d.reg, o.reg); - } else { - ADD(AL, 0, d.reg, o.reg, reg_imm(o.reg, LSL, 1)); - ADD(AL, 0, d.reg, d.reg, b.reg); - } - break; - case 16: - ADD(AL, 0, d.reg, b.reg, reg_imm(o.reg, LSL, 1)); - break; - case 8: - ADD(AL, 0, d.reg, b.reg, o.reg); - break; - } -} - -// ---------------------------------------------------------------------------- -// cheezy register allocator... -// ---------------------------------------------------------------------------- - -void RegisterAllocator::reset() -{ - mRegs.reset(); -} - -int RegisterAllocator::reserveReg(int reg) -{ - return mRegs.reserve(reg); -} - -int RegisterAllocator::obtainReg() -{ - return mRegs.obtain(); -} - -void RegisterAllocator::recycleReg(int reg) -{ - mRegs.recycle(reg); -} - -RegisterAllocator::RegisterFile& RegisterAllocator::registerFile() -{ - return mRegs; -} - -// ---------------------------------------------------------------------------- - -RegisterAllocator::RegisterFile::RegisterFile() - : mRegs(0), mTouched(0), mStatus(0) -{ - reserve(ARMAssemblerInterface::SP); - reserve(ARMAssemblerInterface::PC); -} - -RegisterAllocator::RegisterFile::RegisterFile(const RegisterFile& rhs) - : mRegs(rhs.mRegs), mTouched(rhs.mTouched) -{ -} - -RegisterAllocator::RegisterFile::~RegisterFile() -{ -} - -bool RegisterAllocator::RegisterFile::operator == (const RegisterFile& rhs) const -{ - return (mRegs == rhs.mRegs); -} - -void RegisterAllocator::RegisterFile::reset() -{ - mRegs = mTouched = mStatus = 0; - reserve(ARMAssemblerInterface::SP); - reserve(ARMAssemblerInterface::PC); -} - -int RegisterAllocator::RegisterFile::reserve(int reg) -{ - LOG_ALWAYS_FATAL_IF(isUsed(reg), - "reserving register %d, but already in use", - reg); - mRegs |= (1<<reg); - mTouched |= mRegs; - return reg; -} - -void RegisterAllocator::RegisterFile::reserveSeveral(uint32_t regMask) -{ - mRegs |= regMask; - mTouched |= regMask; -} - -int RegisterAllocator::RegisterFile::isUsed(int reg) const -{ - LOG_ALWAYS_FATAL_IF(reg>=16, "invalid register %d", reg); - return mRegs & (1<<reg); -} - -int RegisterAllocator::RegisterFile::obtain() -{ - const char priorityList[14] = { 0, 1, 2, 3, - 12, 14, 4, 5, - 6, 7, 8, 9, - 10, 11 }; - const int nbreg = sizeof(priorityList); - int i, r; - for (i=0 ; i<nbreg ; i++) { - r = priorityList[i]; - if (!isUsed(r)) { - break; - } - } - // this is not an error anymore because, we'll try again with - // a lower optimization level. - //LOGE_IF(i >= nbreg, "pixelflinger ran out of registers\n"); - if (i >= nbreg) { - mStatus |= OUT_OF_REGISTERS; - // we return SP so we can more easily debug things - // the code will never be run anyway. - return ARMAssemblerInterface::SP; - } - reserve(r); - return r; -} - -bool RegisterAllocator::RegisterFile::hasFreeRegs() const -{ - return ((mRegs & 0xFFFF) == 0xFFFF) ? false : true; -} - -int RegisterAllocator::RegisterFile::countFreeRegs() const -{ - int f = ~mRegs & 0xFFFF; - // now count number of 1 - f = (f & 0x5555) + ((f>>1) & 0x5555); - f = (f & 0x3333) + ((f>>2) & 0x3333); - f = (f & 0x0F0F) + ((f>>4) & 0x0F0F); - f = (f & 0x00FF) + ((f>>8) & 0x00FF); - return f; -} - -void RegisterAllocator::RegisterFile::recycle(int reg) -{ - LOG_FATAL_IF(!isUsed(reg), - "recycling unallocated register %d", - reg); - mRegs &= ~(1<<reg); -} - -void RegisterAllocator::RegisterFile::recycleSeveral(uint32_t regMask) -{ - LOG_FATAL_IF((mRegs & regMask)!=regMask, - "recycling unallocated registers " - "(recycle=%08x, allocated=%08x, unallocated=%08x)", - regMask, mRegs, mRegs®Mask); - mRegs &= ~regMask; -} - -uint32_t RegisterAllocator::RegisterFile::touched() const -{ - return mTouched; -} - -// ---------------------------------------------------------------------------- - -}; // namespace android - diff --git a/libpixelflinger/codeflinger/GGLAssembler.h b/libpixelflinger/codeflinger/GGLAssembler.h deleted file mode 100644 index d1d29f0b0e19619bb560eb165393cd6613358cb1..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/GGLAssembler.h +++ /dev/null @@ -1,554 +0,0 @@ -/* libs/pixelflinger/codeflinger/GGLAssembler.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_GGLASSEMBLER_H -#define ANDROID_GGLASSEMBLER_H - -#include <stdint.h> -#include <sys/types.h> - -#include <private/pixelflinger/ggl_context.h> - -#include "codeflinger/ARMAssemblerProxy.h" - - -namespace android { - -// ---------------------------------------------------------------------------- - -#define CONTEXT_LOAD(REG, FIELD) \ - LDR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD))) - -#define CONTEXT_STORE(REG, FIELD) \ - STR(AL, REG, mBuilderContext.Rctx, immed12_pre(GGL_OFFSETOF(FIELD))) - - -class RegisterAllocator -{ -public: - class RegisterFile; - - RegisterFile& registerFile(); - int reserveReg(int reg); - int obtainReg(); - void recycleReg(int reg); - void reset(); - - class RegisterFile - { - public: - RegisterFile(); - RegisterFile(const RegisterFile& rhs); - ~RegisterFile(); - - void reset(); - - bool operator == (const RegisterFile& rhs) const; - bool operator != (const RegisterFile& rhs) const { - return !operator == (rhs); - } - - int reserve(int reg); - void reserveSeveral(uint32_t regMask); - - void recycle(int reg); - void recycleSeveral(uint32_t regMask); - - int obtain(); - inline int isUsed(int reg) const; - - bool hasFreeRegs() const; - int countFreeRegs() const; - - uint32_t touched() const; - inline uint32_t status() const { return mStatus; } - - enum { - OUT_OF_REGISTERS = 0x1 - }; - - private: - uint32_t mRegs; - uint32_t mTouched; - uint32_t mStatus; - }; - - class Scratch - { - public: - Scratch(RegisterFile& regFile) - : mRegFile(regFile), mScratch(0) { - } - ~Scratch() { - mRegFile.recycleSeveral(mScratch); - } - int obtain() { - int reg = mRegFile.obtain(); - mScratch |= 1<<reg; - return reg; - } - void recycle(int reg) { - mRegFile.recycle(reg); - mScratch &= ~(1<<reg); - } - bool isUsed(int reg) { - return (mScratch & (1<<reg)); - } - int countFreeRegs() { - return mRegFile.countFreeRegs(); - } - private: - RegisterFile& mRegFile; - uint32_t mScratch; - }; - - class Spill - { - public: - Spill(RegisterFile& regFile, ARMAssemblerInterface& gen, uint32_t reglist) - : mRegFile(regFile), mGen(gen), mRegList(reglist), mCount(0) - { - if (reglist) { - int count = 0; - while (reglist) { - count++; - reglist &= ~(1 << (31 - __builtin_clz(reglist))); - } - if (count == 1) { - int reg = 31 - __builtin_clz(mRegList); - mGen.STR(mGen.AL, reg, mGen.SP, mGen.immed12_pre(-4, 1)); - } else { - mGen.STM(mGen.AL, mGen.DB, mGen.SP, 1, mRegList); - } - mRegFile.recycleSeveral(mRegList); - mCount = count; - } - } - ~Spill() { - if (mRegList) { - if (mCount == 1) { - int reg = 31 - __builtin_clz(mRegList); - mGen.LDR(mGen.AL, reg, mGen.SP, mGen.immed12_post(4)); - } else { - mGen.LDM(mGen.AL, mGen.IA, mGen.SP, 1, mRegList); - } - mRegFile.reserveSeveral(mRegList); - } - } - private: - RegisterFile& mRegFile; - ARMAssemblerInterface& mGen; - uint32_t mRegList; - int mCount; - }; - -private: - RegisterFile mRegs; -}; - -// ---------------------------------------------------------------------------- - -class GGLAssembler : public ARMAssemblerProxy, public RegisterAllocator -{ -public: - - GGLAssembler(ARMAssemblerInterface* target); - virtual ~GGLAssembler(); - - uint32_t* base() const { return 0; } // XXX - uint32_t* pc() const { return 0; } // XXX - - void reset(int opt_level); - - virtual void prolog(); - virtual void epilog(uint32_t touched); - - // generate scanline code for given needs - int scanline(const needs_t& needs, context_t const* c); - int scanline_core(const needs_t& needs, context_t const* c); - - enum { - CLEAR_LO = 0x0001, - CLEAR_HI = 0x0002, - CORRUPTIBLE = 0x0004, - FIRST = 0x0008 - }; - - enum { //load/store flags - WRITE_BACK = 0x0001 - }; - - struct reg_t { - reg_t() : reg(-1), flags(0) { - } - reg_t(int r, int f=0) - : reg(r), flags(f) { - } - void setTo(int r, int f=0) { - reg=r; flags=f; - } - int reg; - uint16_t flags; - }; - - struct integer_t : public reg_t { - integer_t() : reg_t(), s(0) { - } - integer_t(int r, int sz=32, int f=0) - : reg_t(r, f), s(sz) { - } - void setTo(int r, int sz=32, int f=0) { - reg_t::setTo(r, f); s=sz; - } - int8_t s; - inline int size() const { return s; } - }; - - struct pixel_t : public reg_t { - pixel_t() : reg_t() { - memset(&format, 0, sizeof(GGLFormat)); - } - pixel_t(int r, const GGLFormat* fmt, int f=0) - : reg_t(r, f), format(*fmt) { - } - void setTo(int r, const GGLFormat* fmt, int f=0) { - reg_t::setTo(r, f); format = *fmt; - } - GGLFormat format; - inline int hi(int c) const { return format.c[c].h; } - inline int low(int c) const { return format.c[c].l; } - inline int mask(int c) const { return ((1<<size(c))-1) << low(c); } - inline int size() const { return format.size*8; } - inline int size(int c) const { return component_size(c); } - inline int component_size(int c) const { return hi(c) - low(c); } - }; - - struct component_t : public reg_t { - component_t() : reg_t(), h(0), l(0) { - } - component_t(int r, int f=0) - : reg_t(r, f), h(0), l(0) { - } - component_t(int r, int lo, int hi, int f=0) - : reg_t(r, f), h(hi), l(lo) { - } - explicit component_t(const integer_t& rhs) - : reg_t(rhs.reg, rhs.flags), h(rhs.s), l(0) { - } - explicit component_t(const pixel_t& rhs, int component) { - setTo( rhs.reg, - rhs.format.c[component].l, - rhs.format.c[component].h, - rhs.flags|CLEAR_LO|CLEAR_HI); - } - void setTo(int r, int lo=0, int hi=0, int f=0) { - reg_t::setTo(r, f); h=hi; l=lo; - } - int8_t h; - int8_t l; - inline int size() const { return h-l; } - }; - - struct pointer_t : public reg_t { - pointer_t() : reg_t(), size(0) { - } - pointer_t(int r, int s, int f=0) - : reg_t(r, f), size(s) { - } - void setTo(int r, int s, int f=0) { - reg_t::setTo(r, f); size=s; - } - int8_t size; - }; - - -private: - struct tex_coord_t { - reg_t s; - reg_t t; - pointer_t ptr; - }; - - struct fragment_parts_t { - uint32_t packed : 1; - uint32_t reload : 2; - uint32_t iterated_packed : 1; - pixel_t iterated; - pointer_t cbPtr; - pointer_t covPtr; - reg_t count; - reg_t argb[4]; - reg_t argb_dx[4]; - reg_t z; - reg_t dither; - pixel_t texel[GGL_TEXTURE_UNIT_COUNT]; - tex_coord_t coords[GGL_TEXTURE_UNIT_COUNT]; - }; - - struct texture_unit_t { - int format_idx; - GGLFormat format; - int bits; - int swrap; - int twrap; - int env; - int pot; - int linear; - uint8_t mask; - uint8_t replaced; - }; - - struct texture_machine_t { - texture_unit_t tmu[GGL_TEXTURE_UNIT_COUNT]; - uint8_t mask; - uint8_t replaced; - uint8_t directTexture; - uint8_t activeUnits; - }; - - struct component_info_t { - bool masked : 1; - bool inDest : 1; - bool needed : 1; - bool replaced : 1; - bool iterated : 1; - bool smooth : 1; - bool blend : 1; - bool fog : 1; - }; - - struct builder_context_t { - context_t const* c; - needs_t needs; - int Rctx; - }; - - template <typename T> - void modify(T& r, Scratch& regs) - { - if (!(r.flags & CORRUPTIBLE)) { - r.reg = regs.obtain(); - r.flags |= CORRUPTIBLE; - } - } - - // helpers - void base_offset(const pointer_t& d, const pointer_t& b, const reg_t& o); - - // texture environement - void modulate( component_t& dest, - const component_t& incoming, - const pixel_t& texel, int component); - - void decal( component_t& dest, - const component_t& incoming, - const pixel_t& texel, int component); - - void blend( component_t& dest, - const component_t& incoming, - const pixel_t& texel, int component, int tmu); - - void add( component_t& dest, - const component_t& incoming, - const pixel_t& texel, int component); - - // load/store stuff - void store(const pointer_t& addr, const pixel_t& src, uint32_t flags=0); - void load(const pointer_t& addr, const pixel_t& dest, uint32_t flags=0); - void extract(integer_t& d, const pixel_t& s, int component); - void extract(component_t& d, const pixel_t& s, int component); - void extract(integer_t& d, int s, int h, int l, int bits=32); - void expand(integer_t& d, const integer_t& s, int dbits); - void expand(integer_t& d, const component_t& s, int dbits); - void expand(component_t& d, const component_t& s, int dbits); - void downshift(pixel_t& d, int component, component_t s, const reg_t& dither); - - - void mul_factor( component_t& d, - const integer_t& v, - const integer_t& f); - - void mul_factor_add( component_t& d, - const integer_t& v, - const integer_t& f, - const component_t& a); - - void component_add( component_t& d, - const integer_t& dst, - const integer_t& src); - - void component_sat( const component_t& v); - - - void build_scanline_prolog( fragment_parts_t& parts, - const needs_t& needs); - - void build_smooth_shade(const fragment_parts_t& parts); - - void build_component( pixel_t& pixel, - const fragment_parts_t& parts, - int component, - Scratch& global_scratches); - - void build_incoming_component( - component_t& temp, - int dst_size, - const fragment_parts_t& parts, - int component, - Scratch& scratches, - Scratch& global_scratches); - - void init_iterated_color(fragment_parts_t& parts, const reg_t& x); - - void build_iterated_color( component_t& fragment, - const fragment_parts_t& parts, - int component, - Scratch& regs); - - void decodeLogicOpNeeds(const needs_t& needs); - - void decodeTMUNeeds(const needs_t& needs, context_t const* c); - - void init_textures( tex_coord_t* coords, - const reg_t& x, - const reg_t& y); - - void build_textures( fragment_parts_t& parts, - Scratch& regs); - - void filter8( const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS); - - void filter16( const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS); - - void filter24( const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS); - - void filter32( const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS); - - void build_texture_environment( component_t& fragment, - const fragment_parts_t& parts, - int component, - Scratch& regs); - - void wrapping( int d, - int coord, int size, - int tx_wrap, int tx_linear); - - void build_fog( component_t& temp, - int component, - Scratch& parent_scratches); - - void build_blending( component_t& in_out, - const pixel_t& pixel, - int component, - Scratch& parent_scratches); - - void build_blend_factor( - integer_t& factor, int f, int component, - const pixel_t& dst_pixel, - integer_t& fragment, - integer_t& fb, - Scratch& scratches); - - void build_blendFOneMinusF( component_t& temp, - const integer_t& factor, - const integer_t& fragment, - const integer_t& fb); - - void build_blendOneMinusFF( component_t& temp, - const integer_t& factor, - const integer_t& fragment, - const integer_t& fb); - - void build_coverage_application(component_t& fragment, - const fragment_parts_t& parts, - Scratch& regs); - - void build_alpha_test(component_t& fragment, const fragment_parts_t& parts); - - enum { Z_TEST=1, Z_WRITE=2 }; - void build_depth_test(const fragment_parts_t& parts, uint32_t mask); - void build_iterate_z(const fragment_parts_t& parts); - void build_iterate_f(const fragment_parts_t& parts); - void build_iterate_texture_coordinates(const fragment_parts_t& parts); - - void build_logic_op(pixel_t& pixel, Scratch& regs); - - void build_masking(pixel_t& pixel, Scratch& regs); - - void build_and_immediate(int d, int s, uint32_t mask, int bits); - - bool isAlphaSourceNeeded() const; - - enum { - FACTOR_SRC=1, FACTOR_DST=2, BLEND_SRC=4, BLEND_DST=8 - }; - - enum { - LOGIC_OP=1, LOGIC_OP_SRC=2, LOGIC_OP_DST=4 - }; - - static int blending_codes(int fs, int fd); - - builder_context_t mBuilderContext; - texture_machine_t mTextureMachine; - component_info_t mInfo[4]; - int mBlending; - int mMasking; - int mAllMasked; - int mLogicOp; - int mAlphaTest; - int mAA; - int mDithering; - int mDepthTest; - - int mSmooth; - int mFog; - pixel_t mDstPixel; - - GGLFormat mCbFormat; - - int mBlendFactorCached; - integer_t mAlphaSource; - - int mBaseRegister; - - int mBlendSrc; - int mBlendDst; - int mBlendSrcA; - int mBlendDstA; - - int mOptLevel; -}; - -// ---------------------------------------------------------------------------- - -}; // namespace android - -#endif // ANDROID_GGLASSEMBLER_H diff --git a/libpixelflinger/codeflinger/armreg.h b/libpixelflinger/codeflinger/armreg.h deleted file mode 100644 index fde81ba89763d3712a4aafca0efec567c2ca7da3..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/armreg.h +++ /dev/null @@ -1,300 +0,0 @@ -/* $NetBSD: armreg.h,v 1.28 2003/10/31 16:30:15 scw Exp $ */ - -/*- - * Copyright (c) 1998, 2001 Ben Harris - * Copyright (c) 1994-1996 Mark Brinicombe. - * Copyright (c) 1994 Brini. - * All rights reserved. - * - * This code is derived from software written for Brini by Mark Brinicombe - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Brini. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/arm/include/armreg.h,v 1.3 2005/11/21 19:06:25 cognet Exp $ - */ - -#ifndef MACHINE_ARMREG_H -#define MACHINE_ARMREG_H -#define INSN_SIZE 4 -#define INSN_COND_MASK 0xf0000000 /* Condition mask */ -#define PSR_MODE 0x0000001f /* mode mask */ -#define PSR_USR26_MODE 0x00000000 -#define PSR_FIQ26_MODE 0x00000001 -#define PSR_IRQ26_MODE 0x00000002 -#define PSR_SVC26_MODE 0x00000003 -#define PSR_USR32_MODE 0x00000010 -#define PSR_FIQ32_MODE 0x00000011 -#define PSR_IRQ32_MODE 0x00000012 -#define PSR_SVC32_MODE 0x00000013 -#define PSR_ABT32_MODE 0x00000017 -#define PSR_UND32_MODE 0x0000001b -#define PSR_SYS32_MODE 0x0000001f -#define PSR_32_MODE 0x00000010 -#define PSR_FLAGS 0xf0000000 /* flags */ - -#define PSR_C_bit (1 << 29) /* carry */ - -/* The high-order byte is always the implementor */ -#define CPU_ID_IMPLEMENTOR_MASK 0xff000000 -#define CPU_ID_ARM_LTD 0x41000000 /* 'A' */ -#define CPU_ID_DEC 0x44000000 /* 'D' */ -#define CPU_ID_INTEL 0x69000000 /* 'i' */ -#define CPU_ID_TI 0x54000000 /* 'T' */ - -/* How to decide what format the CPUID is in. */ -#define CPU_ID_ISOLD(x) (((x) & 0x0000f000) == 0x00000000) -#define CPU_ID_IS7(x) (((x) & 0x0000f000) == 0x00007000) -#define CPU_ID_ISNEW(x) (!CPU_ID_ISOLD(x) && !CPU_ID_IS7(x)) - -/* On ARM3 and ARM6, this byte holds the foundry ID. */ -#define CPU_ID_FOUNDRY_MASK 0x00ff0000 -#define CPU_ID_FOUNDRY_VLSI 0x00560000 - -/* On ARM7 it holds the architecture and variant (sub-model) */ -#define CPU_ID_7ARCH_MASK 0x00800000 -#define CPU_ID_7ARCH_V3 0x00000000 -#define CPU_ID_7ARCH_V4T 0x00800000 -#define CPU_ID_7VARIANT_MASK 0x007f0000 - -/* On more recent ARMs, it does the same, but in a different format */ -#define CPU_ID_ARCH_MASK 0x000f0000 -#define CPU_ID_ARCH_V3 0x00000000 -#define CPU_ID_ARCH_V4 0x00010000 -#define CPU_ID_ARCH_V4T 0x00020000 -#define CPU_ID_ARCH_V5 0x00030000 -#define CPU_ID_ARCH_V5T 0x00040000 -#define CPU_ID_ARCH_V5TE 0x00050000 -#define CPU_ID_VARIANT_MASK 0x00f00000 - -/* Next three nybbles are part number */ -#define CPU_ID_PARTNO_MASK 0x0000fff0 - -/* Intel XScale has sub fields in part number */ -#define CPU_ID_XSCALE_COREGEN_MASK 0x0000e000 /* core generation */ -#define CPU_ID_XSCALE_COREREV_MASK 0x00001c00 /* core revision */ -#define CPU_ID_XSCALE_PRODUCT_MASK 0x000003f0 /* product number */ - -/* And finally, the revision number. */ -#define CPU_ID_REVISION_MASK 0x0000000f - -/* Individual CPUs are probably best IDed by everything but the revision. */ -#define CPU_ID_CPU_MASK 0xfffffff0 - -/* Fake CPU IDs for ARMs without CP15 */ -#define CPU_ID_ARM2 0x41560200 -#define CPU_ID_ARM250 0x41560250 - -/* Pre-ARM7 CPUs -- [15:12] == 0 */ -#define CPU_ID_ARM3 0x41560300 -#define CPU_ID_ARM600 0x41560600 -#define CPU_ID_ARM610 0x41560610 -#define CPU_ID_ARM620 0x41560620 - -/* ARM7 CPUs -- [15:12] == 7 */ -#define CPU_ID_ARM700 0x41007000 /* XXX This is a guess. */ -#define CPU_ID_ARM710 0x41007100 -#define CPU_ID_ARM7500 0x41027100 /* XXX This is a guess. */ -#define CPU_ID_ARM710A 0x41047100 /* inc ARM7100 */ -#define CPU_ID_ARM7500FE 0x41077100 -#define CPU_ID_ARM710T 0x41807100 -#define CPU_ID_ARM720T 0x41807200 -#define CPU_ID_ARM740T8K 0x41807400 /* XXX no MMU, 8KB cache */ -#define CPU_ID_ARM740T4K 0x41817400 /* XXX no MMU, 4KB cache */ - -/* Post-ARM7 CPUs */ -#define CPU_ID_ARM810 0x41018100 -#define CPU_ID_ARM920T 0x41129200 -#define CPU_ID_ARM920T_ALT 0x41009200 -#define CPU_ID_ARM922T 0x41029220 -#define CPU_ID_ARM940T 0x41029400 /* XXX no MMU */ -#define CPU_ID_ARM946ES 0x41049460 /* XXX no MMU */ -#define CPU_ID_ARM966ES 0x41049660 /* XXX no MMU */ -#define CPU_ID_ARM966ESR1 0x41059660 /* XXX no MMU */ -#define CPU_ID_ARM1020E 0x4115a200 /* (AKA arm10 rev 1) */ -#define CPU_ID_ARM1022ES 0x4105a220 -#define CPU_ID_SA110 0x4401a100 -#define CPU_ID_SA1100 0x4401a110 -#define CPU_ID_TI925T 0x54029250 -#define CPU_ID_SA1110 0x6901b110 -#define CPU_ID_IXP1200 0x6901c120 -#define CPU_ID_80200 0x69052000 -#define CPU_ID_PXA250 0x69052100 /* sans core revision */ -#define CPU_ID_PXA210 0x69052120 -#define CPU_ID_PXA250A 0x69052100 /* 1st version Core */ -#define CPU_ID_PXA210A 0x69052120 /* 1st version Core */ -#define CPU_ID_PXA250B 0x69052900 /* 3rd version Core */ -#define CPU_ID_PXA210B 0x69052920 /* 3rd version Core */ -#define CPU_ID_PXA250C 0x69052d00 /* 4th version Core */ -#define CPU_ID_PXA210C 0x69052d20 /* 4th version Core */ -#define CPU_ID_80321_400 0x69052420 -#define CPU_ID_80321_600 0x69052430 -#define CPU_ID_80321_400_B0 0x69052c20 -#define CPU_ID_80321_600_B0 0x69052c30 -#define CPU_ID_IXP425_533 0x690541c0 -#define CPU_ID_IXP425_400 0x690541d0 -#define CPU_ID_IXP425_266 0x690541f0 - -/* ARM3-specific coprocessor 15 registers */ -#define ARM3_CP15_FLUSH 1 -#define ARM3_CP15_CONTROL 2 -#define ARM3_CP15_CACHEABLE 3 -#define ARM3_CP15_UPDATEABLE 4 -#define ARM3_CP15_DISRUPTIVE 5 - -/* ARM3 Control register bits */ -#define ARM3_CTL_CACHE_ON 0x00000001 -#define ARM3_CTL_SHARED 0x00000002 -#define ARM3_CTL_MONITOR 0x00000004 - -/* - * Post-ARM3 CP15 registers: - * - * 1 Control register - * - * 2 Translation Table Base - * - * 3 Domain Access Control - * - * 4 Reserved - * - * 5 Fault Status - * - * 6 Fault Address - * - * 7 Cache/write-buffer Control - * - * 8 TLB Control - * - * 9 Cache Lockdown - * - * 10 TLB Lockdown - * - * 11 Reserved - * - * 12 Reserved - * - * 13 Process ID (for FCSE) - * - * 14 Reserved - * - * 15 Implementation Dependent - */ - -/* Some of the definitions below need cleaning up for V3/V4 architectures */ - -/* CPU control register (CP15 register 1) */ -#define CPU_CONTROL_MMU_ENABLE 0x00000001 /* M: MMU/Protection unit enable */ -#define CPU_CONTROL_AFLT_ENABLE 0x00000002 /* A: Alignment fault enable */ -#define CPU_CONTROL_DC_ENABLE 0x00000004 /* C: IDC/DC enable */ -#define CPU_CONTROL_WBUF_ENABLE 0x00000008 /* W: Write buffer enable */ -#define CPU_CONTROL_32BP_ENABLE 0x00000010 /* P: 32-bit exception handlers */ -#define CPU_CONTROL_32BD_ENABLE 0x00000020 /* D: 32-bit addressing */ -#define CPU_CONTROL_LABT_ENABLE 0x00000040 /* L: Late abort enable */ -#define CPU_CONTROL_BEND_ENABLE 0x00000080 /* B: Big-endian mode */ -#define CPU_CONTROL_SYST_ENABLE 0x00000100 /* S: System protection bit */ -#define CPU_CONTROL_ROM_ENABLE 0x00000200 /* R: ROM protection bit */ -#define CPU_CONTROL_CPCLK 0x00000400 /* F: Implementation defined */ -#define CPU_CONTROL_BPRD_ENABLE 0x00000800 /* Z: Branch prediction enable */ -#define CPU_CONTROL_IC_ENABLE 0x00001000 /* I: IC enable */ -#define CPU_CONTROL_VECRELOC 0x00002000 /* V: Vector relocation */ -#define CPU_CONTROL_ROUNDROBIN 0x00004000 /* RR: Predictable replacement */ -#define CPU_CONTROL_V4COMPAT 0x00008000 /* L4: ARMv4 compat LDR R15 etc */ - -#define CPU_CONTROL_IDC_ENABLE CPU_CONTROL_DC_ENABLE - -/* XScale Auxillary Control Register (CP15 register 1, opcode2 1) */ -#define XSCALE_AUXCTL_K 0x00000001 /* dis. write buffer coalescing */ -#define XSCALE_AUXCTL_P 0x00000002 /* ECC protect page table access */ -#define XSCALE_AUXCTL_MD_WB_RA 0x00000000 /* mini-D$ wb, read-allocate */ -#define XSCALE_AUXCTL_MD_WB_RWA 0x00000010 /* mini-D$ wb, read/write-allocate */ -#define XSCALE_AUXCTL_MD_WT 0x00000020 /* mini-D$ wt, read-allocate */ -#define XSCALE_AUXCTL_MD_MASK 0x00000030 - -/* Cache type register definitions */ -#define CPU_CT_ISIZE(x) ((x) & 0xfff) /* I$ info */ -#define CPU_CT_DSIZE(x) (((x) >> 12) & 0xfff) /* D$ info */ -#define CPU_CT_S (1U << 24) /* split cache */ -#define CPU_CT_CTYPE(x) (((x) >> 25) & 0xf) /* cache type */ - -#define CPU_CT_CTYPE_WT 0 /* write-through */ -#define CPU_CT_CTYPE_WB1 1 /* write-back, clean w/ read */ -#define CPU_CT_CTYPE_WB2 2 /* w/b, clean w/ cp15,7 */ -#define CPU_CT_CTYPE_WB6 6 /* w/b, cp15,7, lockdown fmt A */ -#define CPU_CT_CTYPE_WB7 7 /* w/b, cp15,7, lockdown fmt B */ - -#define CPU_CT_xSIZE_LEN(x) ((x) & 0x3) /* line size */ -#define CPU_CT_xSIZE_M (1U << 2) /* multiplier */ -#define CPU_CT_xSIZE_ASSOC(x) (((x) >> 3) & 0x7) /* associativity */ -#define CPU_CT_xSIZE_SIZE(x) (((x) >> 6) & 0x7) /* size */ - -/* Fault status register definitions */ - -#define FAULT_TYPE_MASK 0x0f -#define FAULT_USER 0x10 - -#define FAULT_WRTBUF_0 0x00 /* Vector Exception */ -#define FAULT_WRTBUF_1 0x02 /* Terminal Exception */ -#define FAULT_BUSERR_0 0x04 /* External Abort on Linefetch -- Section */ -#define FAULT_BUSERR_1 0x06 /* External Abort on Linefetch -- Page */ -#define FAULT_BUSERR_2 0x08 /* External Abort on Non-linefetch -- Section */ -#define FAULT_BUSERR_3 0x0a /* External Abort on Non-linefetch -- Page */ -#define FAULT_BUSTRNL1 0x0c /* External abort on Translation -- Level 1 */ -#define FAULT_BUSTRNL2 0x0e /* External abort on Translation -- Level 2 */ -#define FAULT_ALIGN_0 0x01 /* Alignment */ -#define FAULT_ALIGN_1 0x03 /* Alignment */ -#define FAULT_TRANS_S 0x05 /* Translation -- Section */ -#define FAULT_TRANS_P 0x07 /* Translation -- Page */ -#define FAULT_DOMAIN_S 0x09 /* Domain -- Section */ -#define FAULT_DOMAIN_P 0x0b /* Domain -- Page */ -#define FAULT_PERM_S 0x0d /* Permission -- Section */ -#define FAULT_PERM_P 0x0f /* Permission -- Page */ - -#define FAULT_IMPRECISE 0x400 /* Imprecise exception (XSCALE) */ - -/* - * Address of the vector page, low and high versions. - */ -#define ARM_VECTORS_LOW 0x00000000U -#define ARM_VECTORS_HIGH 0xffff0000U - -/* - * ARM Instructions - * - * 3 3 2 2 2 - * 1 0 9 8 7 0 - * +-------+-------------------------------------------------------+ - * | cond | instruction dependant | - * |c c c c| | - * +-------+-------------------------------------------------------+ - */ - -#define INSN_SIZE 4 /* Always 4 bytes */ -#define INSN_COND_MASK 0xf0000000 /* Condition mask */ -#define INSN_COND_AL 0xe0000000 /* Always condition */ - -#endif /* !MACHINE_ARMREG_H */ diff --git a/libpixelflinger/codeflinger/blending.cpp b/libpixelflinger/codeflinger/blending.cpp deleted file mode 100644 index f10217b74a7a7b38b08298cfd595813411eedac5..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/blending.cpp +++ /dev/null @@ -1,682 +0,0 @@ -/* libs/pixelflinger/codeflinger/blending.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include "codeflinger/GGLAssembler.h" - - -namespace android { - -void GGLAssembler::build_fog( - component_t& temp, // incomming fragment / output - int component, - Scratch& regs) -{ - if (mInfo[component].fog) { - Scratch scratches(registerFile()); - comment("fog"); - - integer_t fragment(temp.reg, temp.h, temp.flags); - if (!(temp.flags & CORRUPTIBLE)) { - temp.reg = regs.obtain(); - temp.flags |= CORRUPTIBLE; - } - - integer_t fogColor(scratches.obtain(), 8, CORRUPTIBLE); - LDRB(AL, fogColor.reg, mBuilderContext.Rctx, - immed12_pre(GGL_OFFSETOF(state.fog.color[component]))); - - integer_t factor(scratches.obtain(), 16, CORRUPTIBLE); - CONTEXT_LOAD(factor.reg, generated_vars.f); - - // clamp fog factor (TODO: see if there is a way to guarantee - // we won't overflow, when setting the iterators) - BIC(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, ASR, 31)); - CMP(AL, factor.reg, imm( 0x10000 )); - MOV(HS, 0, factor.reg, imm( 0x10000 )); - - build_blendFOneMinusF(temp, factor, fragment, fogColor); - } -} - -void GGLAssembler::build_blending( - component_t& temp, // incomming fragment / output - const pixel_t& pixel, // framebuffer - int component, - Scratch& regs) -{ - if (!mInfo[component].blend) - return; - - int fs = component==GGLFormat::ALPHA ? mBlendSrcA : mBlendSrc; - int fd = component==GGLFormat::ALPHA ? mBlendDstA : mBlendDst; - if (fs==GGL_SRC_ALPHA_SATURATE && component==GGLFormat::ALPHA) - fs = GGL_ONE; - const int blending = blending_codes(fs, fd); - if (!temp.size()) { - // here, blending will produce something which doesn't depend on - // that component (eg: GL_ZERO:GL_*), so the register has not been - // allocated yet. Will never be used as a source. - temp = component_t(regs.obtain(), CORRUPTIBLE); - } - - // we are doing real blending... - // fb: extracted dst - // fragment: extracted src - // temp: component_t(fragment) and result - - // scoped register allocator - Scratch scratches(registerFile()); - comment("blending"); - - // we can optimize these cases a bit... - // (1) saturation is not needed - // (2) we can use only one multiply instead of 2 - // (3) we can reduce the register pressure - // R = S*f + D*(1-f) = (S-D)*f + D - // R = S*(1-f) + D*f = (D-S)*f + S - - const bool same_factor_opt1 = - (fs==GGL_DST_COLOR && fd==GGL_ONE_MINUS_DST_COLOR) || - (fs==GGL_SRC_COLOR && fd==GGL_ONE_MINUS_SRC_COLOR) || - (fs==GGL_DST_ALPHA && fd==GGL_ONE_MINUS_DST_ALPHA) || - (fs==GGL_SRC_ALPHA && fd==GGL_ONE_MINUS_SRC_ALPHA); - - const bool same_factor_opt2 = - (fs==GGL_ONE_MINUS_DST_COLOR && fd==GGL_DST_COLOR) || - (fs==GGL_ONE_MINUS_SRC_COLOR && fd==GGL_SRC_COLOR) || - (fs==GGL_ONE_MINUS_DST_ALPHA && fd==GGL_DST_ALPHA) || - (fs==GGL_ONE_MINUS_SRC_ALPHA && fd==GGL_SRC_ALPHA); - - - // XXX: we could also optimize these cases: - // R = S*f + D*f = (S+D)*f - // R = S*(1-f) + D*(1-f) = (S+D)*(1-f) - // R = S*D + D*S = 2*S*D - - - // see if we need to extract 'component' from the destination (fb) - integer_t fb; - if (blending & (BLEND_DST|FACTOR_DST)) { - fb.setTo(scratches.obtain(), 32); - extract(fb, pixel, component); - if (mDithering) { - // XXX: maybe what we should do instead, is simply - // expand fb -or- fragment to the larger of the two - if (fb.size() < temp.size()) { - // for now we expand 'fb' to min(fragment, 8) - int new_size = temp.size() < 8 ? temp.size() : 8; - expand(fb, fb, new_size); - } - } - } - - - // convert input fragment to integer_t - if (temp.l && (temp.flags & CORRUPTIBLE)) { - MOV(AL, 0, temp.reg, reg_imm(temp.reg, LSR, temp.l)); - temp.h -= temp.l; - temp.l = 0; - } - integer_t fragment(temp.reg, temp.size(), temp.flags); - - // if not done yet, convert input fragment to integer_t - if (temp.l) { - // here we know temp is not CORRUPTIBLE - fragment.reg = scratches.obtain(); - MOV(AL, 0, fragment.reg, reg_imm(temp.reg, LSR, temp.l)); - fragment.flags |= CORRUPTIBLE; - } - - if (!(temp.flags & CORRUPTIBLE)) { - // temp is not corruptible, but since it's the destination it - // will be modified, so we need to allocate a new register. - temp.reg = regs.obtain(); - temp.flags &= ~CORRUPTIBLE; - fragment.flags &= ~CORRUPTIBLE; - } - - if ((blending & BLEND_SRC) && !same_factor_opt1) { - // source (fragment) is needed for the blending stage - // so it's not CORRUPTIBLE (unless we're doing same_factor_opt1) - fragment.flags &= ~CORRUPTIBLE; - } - - - if (same_factor_opt1) { - // R = S*f + D*(1-f) = (S-D)*f + D - integer_t factor; - build_blend_factor(factor, fs, - component, pixel, fragment, fb, scratches); - // fb is always corruptible from this point - fb.flags |= CORRUPTIBLE; - build_blendFOneMinusF(temp, factor, fragment, fb); - } else if (same_factor_opt2) { - // R = S*(1-f) + D*f = (D-S)*f + S - integer_t factor; - // fb is always corrruptible here - fb.flags |= CORRUPTIBLE; - build_blend_factor(factor, fd, - component, pixel, fragment, fb, scratches); - build_blendOneMinusFF(temp, factor, fragment, fb); - } else { - integer_t src_factor; - integer_t dst_factor; - - // if destination (fb) is not needed for the blending stage, - // then it can be marked as CORRUPTIBLE - if (!(blending & BLEND_DST)) { - fb.flags |= CORRUPTIBLE; - } - - // XXX: try to mark some registers as CORRUPTIBLE - // in most case we could make those corruptible - // when we're processing the last component - // but not always, for instance - // when fragment is constant and not reloaded - // when fb is needed for logic-ops or masking - // when a register is aliased (for instance with mAlphaSource) - - // blend away... - if (fs==GGL_ZERO) { - if (fd==GGL_ZERO) { // R = 0 - // already taken care of - } else if (fd==GGL_ONE) { // R = D - // already taken care of - } else { // R = D*fd - // compute fd - build_blend_factor(dst_factor, fd, - component, pixel, fragment, fb, scratches); - mul_factor(temp, fb, dst_factor); - } - } else if (fs==GGL_ONE) { - if (fd==GGL_ZERO) { // R = S - // NOP, taken care of - } else if (fd==GGL_ONE) { // R = S + D - component_add(temp, fb, fragment); // args order matters - component_sat(temp); - } else { // R = S + D*fd - // compute fd - build_blend_factor(dst_factor, fd, - component, pixel, fragment, fb, scratches); - mul_factor_add(temp, fb, dst_factor, component_t(fragment)); - if (fd==GGL_ONE_MINUS_SRC_ALPHA) { - // XXX: in theory this is not correct, we should - // saturate here. However, this mode is often - // used for displaying alpha-premultiplied graphics, - // in which case, saturation is not necessary. - // unfortunatelly, we have no way to know. - // This is a case, where we sacrifice correctness for - // performance. we should probably have some heuristics. - } else { - component_sat(temp); - } - } - } else { - // compute fs - build_blend_factor(src_factor, fs, - component, pixel, fragment, fb, scratches); - if (fd==GGL_ZERO) { // R = S*fs - mul_factor(temp, fragment, src_factor); - } else if (fd==GGL_ONE) { // R = S*fs + D - mul_factor_add(temp, fragment, src_factor, component_t(fb)); - component_sat(temp); - } else { // R = S*fs + D*fd - mul_factor(temp, fragment, src_factor); - if (scratches.isUsed(src_factor.reg)) - scratches.recycle(src_factor.reg); - // compute fd - build_blend_factor(dst_factor, fd, - component, pixel, fragment, fb, scratches); - mul_factor_add(temp, fb, dst_factor, temp); - if (!same_factor_opt1 && !same_factor_opt2) { - component_sat(temp); - } - } - } - } - - // now we can be corrupted (it's the dest) - temp.flags |= CORRUPTIBLE; -} - -void GGLAssembler::build_blend_factor( - integer_t& factor, int f, int component, - const pixel_t& dst_pixel, - integer_t& fragment, - integer_t& fb, - Scratch& scratches) -{ - integer_t src_alpha(fragment); - - // src_factor/dst_factor won't be used after blending, - // so it's fine to mark them as CORRUPTIBLE (if not aliased) - factor.flags |= CORRUPTIBLE; - - switch(f) { - case GGL_ONE_MINUS_SRC_ALPHA: - case GGL_SRC_ALPHA: - if (component==GGLFormat::ALPHA && !isAlphaSourceNeeded()) { - // we're processing alpha, so we already have - // src-alpha in fragment, and we need src-alpha just this time. - } else { - // alpha-src will be needed for other components - if (!mBlendFactorCached || mBlendFactorCached==f) { - src_alpha = mAlphaSource; - factor = mAlphaSource; - factor.flags &= ~CORRUPTIBLE; - // we already computed the blend factor before, nothing to do. - if (mBlendFactorCached) - return; - // this is the first time, make sure to compute the blend - // factor properly. - mBlendFactorCached = f; - break; - } else { - // we have a cached alpha blend factor, but we want another one, - // this should really not happen because by construction, - // we cannot have BOTH source and destination - // blend factors use ALPHA *and* ONE_MINUS_ALPHA (because - // the blending stage uses the f/(1-f) optimization - - // for completeness, we handle this case though. Since there - // are only 2 choices, this meens we want "the other one" - // (1-factor) - factor = mAlphaSource; - factor.flags &= ~CORRUPTIBLE; - RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s))); - mBlendFactorCached = f; - return; - } - } - // fall-through... - case GGL_ONE_MINUS_DST_COLOR: - case GGL_DST_COLOR: - case GGL_ONE_MINUS_SRC_COLOR: - case GGL_SRC_COLOR: - case GGL_ONE_MINUS_DST_ALPHA: - case GGL_DST_ALPHA: - case GGL_SRC_ALPHA_SATURATE: - // help us find out what register we can use for the blend-factor - // CORRUPTIBLE registers are chosen first, or a new one is allocated. - if (fragment.flags & CORRUPTIBLE) { - factor.setTo(fragment.reg, 32, CORRUPTIBLE); - fragment.flags &= ~CORRUPTIBLE; - } else if (fb.flags & CORRUPTIBLE) { - factor.setTo(fb.reg, 32, CORRUPTIBLE); - fb.flags &= ~CORRUPTIBLE; - } else { - factor.setTo(scratches.obtain(), 32, CORRUPTIBLE); - } - break; - } - - // XXX: doesn't work if size==1 - - switch(f) { - case GGL_ONE_MINUS_DST_COLOR: - case GGL_DST_COLOR: - factor.s = fb.s; - ADD(AL, 0, factor.reg, fb.reg, reg_imm(fb.reg, LSR, fb.s-1)); - break; - case GGL_ONE_MINUS_SRC_COLOR: - case GGL_SRC_COLOR: - factor.s = fragment.s; - ADD(AL, 0, factor.reg, fragment.reg, - reg_imm(fragment.reg, LSR, fragment.s-1)); - break; - case GGL_ONE_MINUS_SRC_ALPHA: - case GGL_SRC_ALPHA: - factor.s = src_alpha.s; - ADD(AL, 0, factor.reg, src_alpha.reg, - reg_imm(src_alpha.reg, LSR, src_alpha.s-1)); - break; - case GGL_ONE_MINUS_DST_ALPHA: - case GGL_DST_ALPHA: - // XXX: should be precomputed - extract(factor, dst_pixel, GGLFormat::ALPHA); - ADD(AL, 0, factor.reg, factor.reg, - reg_imm(factor.reg, LSR, factor.s-1)); - break; - case GGL_SRC_ALPHA_SATURATE: - // XXX: should be precomputed - // XXX: f = min(As, 1-Ad) - // btw, we're guaranteed that Ad's size is <= 8, because - // it's extracted from the framebuffer - break; - } - - switch(f) { - case GGL_ONE_MINUS_DST_COLOR: - case GGL_ONE_MINUS_SRC_COLOR: - case GGL_ONE_MINUS_DST_ALPHA: - case GGL_ONE_MINUS_SRC_ALPHA: - RSB(AL, 0, factor.reg, factor.reg, imm((1<<factor.s))); - } - - // don't need more than 8-bits for the blend factor - // and this will prevent overflows in the multiplies later - if (factor.s > 8) { - MOV(AL, 0, factor.reg, reg_imm(factor.reg, LSR, factor.s-8)); - factor.s = 8; - } -} - -int GGLAssembler::blending_codes(int fs, int fd) -{ - int blending = 0; - switch(fs) { - case GGL_ONE: - blending |= BLEND_SRC; - break; - - case GGL_ONE_MINUS_DST_COLOR: - case GGL_DST_COLOR: - blending |= FACTOR_DST|BLEND_SRC; - break; - case GGL_ONE_MINUS_DST_ALPHA: - case GGL_DST_ALPHA: - // no need to extract 'component' from the destination - // for the blend factor, because we need ALPHA only. - blending |= BLEND_SRC; - break; - - case GGL_ONE_MINUS_SRC_COLOR: - case GGL_SRC_COLOR: - blending |= FACTOR_SRC|BLEND_SRC; - break; - case GGL_ONE_MINUS_SRC_ALPHA: - case GGL_SRC_ALPHA: - case GGL_SRC_ALPHA_SATURATE: - blending |= FACTOR_SRC|BLEND_SRC; - break; - } - switch(fd) { - case GGL_ONE: - blending |= BLEND_DST; - break; - - case GGL_ONE_MINUS_DST_COLOR: - case GGL_DST_COLOR: - blending |= FACTOR_DST|BLEND_DST; - break; - case GGL_ONE_MINUS_DST_ALPHA: - case GGL_DST_ALPHA: - blending |= FACTOR_DST|BLEND_DST; - break; - - case GGL_ONE_MINUS_SRC_COLOR: - case GGL_SRC_COLOR: - blending |= FACTOR_SRC|BLEND_DST; - break; - case GGL_ONE_MINUS_SRC_ALPHA: - case GGL_SRC_ALPHA: - // no need to extract 'component' from the source - // for the blend factor, because we need ALPHA only. - blending |= BLEND_DST; - break; - } - return blending; -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::build_blendFOneMinusF( - component_t& temp, - const integer_t& factor, - const integer_t& fragment, - const integer_t& fb) -{ - // R = S*f + D*(1-f) = (S-D)*f + D - Scratch scratches(registerFile()); - // compute S-D - integer_t diff(fragment.flags & CORRUPTIBLE ? - fragment.reg : scratches.obtain(), fb.size(), CORRUPTIBLE); - const int shift = fragment.size() - fb.size(); - if (shift>0) RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift)); - else if (shift<0) RSB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift)); - else RSB(AL, 0, diff.reg, fb.reg, fragment.reg); - mul_factor_add(temp, diff, factor, component_t(fb)); -} - -void GGLAssembler::build_blendOneMinusFF( - component_t& temp, - const integer_t& factor, - const integer_t& fragment, - const integer_t& fb) -{ - // R = S*f + D*(1-f) = (S-D)*f + D - Scratch scratches(registerFile()); - // compute D-S - integer_t diff(fb.flags & CORRUPTIBLE ? - fb.reg : scratches.obtain(), fb.size(), CORRUPTIBLE); - const int shift = fragment.size() - fb.size(); - if (shift>0) SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSR, shift)); - else if (shift<0) SUB(AL, 0, diff.reg, fb.reg, reg_imm(fragment.reg, LSL,-shift)); - else SUB(AL, 0, diff.reg, fb.reg, fragment.reg); - mul_factor_add(temp, diff, factor, component_t(fragment)); -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::mul_factor( component_t& d, - const integer_t& v, - const integer_t& f) -{ - int vs = v.size(); - int fs = f.size(); - int ms = vs+fs; - - // XXX: we could have special cases for 1 bit mul - - // all this code below to use the best multiply instruction - // wrt the parameters size. We take advantage of the fact - // that the 16-bits multiplies allow a 16-bit shift - // The trick is that we just make sure that we have at least 8-bits - // per component (which is enough for a 8 bits display). - - int xy; - int vshift = 0; - int fshift = 0; - int smulw = 0; - - if (vs<16) { - if (fs<16) { - xy = xyBB; - } else if (GGL_BETWEEN(fs, 24, 31)) { - ms -= 16; - xy = xyTB; - } else { - // eg: 15 * 18 -> 15 * 15 - fshift = fs - 15; - ms -= fshift; - xy = xyBB; - } - } else if (GGL_BETWEEN(vs, 24, 31)) { - if (fs<16) { - ms -= 16; - xy = xyTB; - } else if (GGL_BETWEEN(fs, 24, 31)) { - ms -= 32; - xy = xyTT; - } else { - // eg: 24 * 18 -> 8 * 18 - fshift = fs - 15; - ms -= 16 + fshift; - xy = xyTB; - } - } else { - if (fs<16) { - // eg: 18 * 15 -> 15 * 15 - vshift = vs - 15; - ms -= vshift; - xy = xyBB; - } else if (GGL_BETWEEN(fs, 24, 31)) { - // eg: 18 * 24 -> 15 * 8 - vshift = vs - 15; - ms -= 16 + vshift; - xy = xyBT; - } else { - // eg: 18 * 18 -> (15 * 18)>>16 - fshift = fs - 15; - ms -= 16 + fshift; - xy = yB; //XXX SMULWB - smulw = 1; - } - } - - LOGE_IF(ms>=32, "mul_factor overflow vs=%d, fs=%d", vs, fs); - - int vreg = v.reg; - int freg = f.reg; - if (vshift) { - MOV(AL, 0, d.reg, reg_imm(vreg, LSR, vshift)); - vreg = d.reg; - } - if (fshift) { - MOV(AL, 0, d.reg, reg_imm(vreg, LSR, fshift)); - freg = d.reg; - } - if (smulw) SMULW(AL, xy, d.reg, vreg, freg); - else SMUL(AL, xy, d.reg, vreg, freg); - - - d.h = ms; - if (mDithering) { - d.l = 0; - } else { - d.l = fs; - d.flags |= CLEAR_LO; - } -} - -void GGLAssembler::mul_factor_add( component_t& d, - const integer_t& v, - const integer_t& f, - const component_t& a) -{ - // XXX: we could have special cases for 1 bit mul - Scratch scratches(registerFile()); - - int vs = v.size(); - int fs = f.size(); - int as = a.h; - int ms = vs+fs; - - LOGE_IF(ms>=32, "mul_factor_add overflow vs=%d, fs=%d, as=%d", vs, fs, as); - - integer_t add(a.reg, a.h, a.flags); - - // 'a' is a component_t but it is guaranteed to have - // its high bits set to 0. However in the dithering case, - // we can't get away with truncating the potentially bad bits - // so extraction is needed. - - if ((mDithering) && (a.size() < ms)) { - // we need to expand a - if (!(a.flags & CORRUPTIBLE)) { - // ... but it's not corruptible, so we need to pick a - // temporary register. - // Try to uses the destination register first (it's likely - // to be usable, unless it aliases an input). - if (d.reg!=a.reg && d.reg!=v.reg && d.reg!=f.reg) { - add.reg = d.reg; - } else { - add.reg = scratches.obtain(); - } - } - expand(add, a, ms); // extracts and expands - as = ms; - } - - if (ms == as) { - if (vs<16 && fs<16) SMLABB(AL, d.reg, v.reg, f.reg, add.reg); - else MLA(AL, 0, d.reg, v.reg, f.reg, add.reg); - } else { - int temp = d.reg; - if (temp == add.reg) { - // the mul will modify add.reg, we need an intermediary reg - if (v.flags & CORRUPTIBLE) temp = v.reg; - else if (f.flags & CORRUPTIBLE) temp = f.reg; - else temp = scratches.obtain(); - } - - if (vs<16 && fs<16) SMULBB(AL, temp, v.reg, f.reg); - else MUL(AL, 0, temp, v.reg, f.reg); - - if (ms>as) { - ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSL, ms-as)); - } else if (ms<as) { - // not sure if we should expand the mul instead? - ADD(AL, 0, d.reg, temp, reg_imm(add.reg, LSR, as-ms)); - } - } - - d.h = ms; - if (mDithering) { - d.l = a.l; - } else { - d.l = fs>a.l ? fs : a.l; - d.flags |= CLEAR_LO; - } -} - -void GGLAssembler::component_add(component_t& d, - const integer_t& dst, const integer_t& src) -{ - // here we're guaranteed that fragment.size() >= fb.size() - const int shift = src.size() - dst.size(); - if (!shift) { - ADD(AL, 0, d.reg, src.reg, dst.reg); - } else { - ADD(AL, 0, d.reg, src.reg, reg_imm(dst.reg, LSL, shift)); - } - - d.h = src.size(); - if (mDithering) { - d.l = 0; - } else { - d.l = shift; - d.flags |= CLEAR_LO; - } -} - -void GGLAssembler::component_sat(const component_t& v) -{ - const int one = ((1<<v.size())-1)<<v.l; - CMP(AL, v.reg, imm( 1<<v.h )); - if (isValidImmediate(one)) { - MOV(HS, 0, v.reg, imm( one )); - } else if (isValidImmediate(~one)) { - MVN(HS, 0, v.reg, imm( ~one )); - } else { - MOV(HS, 0, v.reg, imm( 1<<v.h )); - SUB(HS, 0, v.reg, v.reg, imm( 1<<v.l )); - } -} - -// ---------------------------------------------------------------------------- - -}; // namespace android - diff --git a/libpixelflinger/codeflinger/disassem.c b/libpixelflinger/codeflinger/disassem.c deleted file mode 100644 index 4676da0d82dcfd74ab0164ee505bdf31e74c8bc5..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/disassem.c +++ /dev/null @@ -1,702 +0,0 @@ -/* $NetBSD: disassem.c,v 1.14 2003/03/27 16:58:36 mycroft Exp $ */ - -/*- - * Copyright (c) 1996 Mark Brinicombe. - * Copyright (c) 1996 Brini. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Brini. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY BRINI ``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 BRINI 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. - * - * RiscBSD kernel project - * - * db_disasm.c - * - * Kernel disassembler - * - * Created : 10/02/96 - * - * Structured after the sparc/sparc/db_disasm.c by David S. Miller & - * Paul Kranenburg - * - * This code is not complete. Not all instructions are disassembled. - */ - -#include <sys/cdefs.h> -//__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/arm/arm/disassem.c,v 1.2 2005/01/05 21:58:47 imp Exp $"); -#include <sys/param.h> -#include <stdio.h> - -#include "disassem.h" -#include "armreg.h" -//#include <ddb/ddb.h> - -/* - * General instruction format - * - * insn[cc][mod] [operands] - * - * Those fields with an uppercase format code indicate that the field - * follows directly after the instruction before the separator i.e. - * they modify the instruction rather than just being an operand to - * the instruction. The only exception is the writeback flag which - * follows a operand. - * - * - * 2 - print Operand 2 of a data processing instruction - * d - destination register (bits 12-15) - * n - n register (bits 16-19) - * s - s register (bits 8-11) - * o - indirect register rn (bits 16-19) (used by swap) - * m - m register (bits 0-3) - * a - address operand of ldr/str instruction - * e - address operand of ldrh/strh instruction - * l - register list for ldm/stm instruction - * f - 1st fp operand (register) (bits 12-14) - * g - 2nd fp operand (register) (bits 16-18) - * h - 3rd fp operand (register/immediate) (bits 0-4) - * b - branch address - * t - thumb branch address (bits 24, 0-23) - * k - breakpoint comment (bits 0-3, 8-19) - * X - block transfer type - * Y - block transfer type (r13 base) - * c - comment field bits(0-23) - * p - saved or current status register - * F - PSR transfer fields - * D - destination-is-r15 (P) flag on TST, TEQ, CMP, CMN - * L - co-processor transfer size - * S - set status flag - * P - fp precision - * Q - fp precision (for ldf/stf) - * R - fp rounding - * v - co-processor data transfer registers + addressing mode - * W - writeback flag - * x - instruction in hex - * # - co-processor number - * y - co-processor data processing registers - * z - co-processor register transfer registers - */ - -struct arm32_insn { - u_int mask; - u_int pattern; - char* name; - char* format; -}; - -static const struct arm32_insn arm32_i[] = { - { 0x0fffffff, 0x0ff00000, "imb", "c" }, /* Before swi */ - { 0x0fffffff, 0x0ff00001, "imbrange", "c" }, /* Before swi */ - { 0x0f000000, 0x0f000000, "swi", "c" }, - { 0xfe000000, 0xfa000000, "blx", "t" }, /* Before b and bl */ - { 0x0f000000, 0x0a000000, "b", "b" }, - { 0x0f000000, 0x0b000000, "bl", "b" }, - { 0x0fe000f0, 0x00000090, "mul", "Snms" }, - { 0x0fe000f0, 0x00200090, "mla", "Snmsd" }, - { 0x0fe000f0, 0x00800090, "umull", "Sdnms" }, - { 0x0fe000f0, 0x00c00090, "smull", "Sdnms" }, - { 0x0fe000f0, 0x00a00090, "umlal", "Sdnms" }, - { 0x0fe000f0, 0x00e00090, "smlal", "Sdnms" }, - { 0x0d700000, 0x04200000, "strt", "daW" }, - { 0x0d700000, 0x04300000, "ldrt", "daW" }, - { 0x0d700000, 0x04600000, "strbt", "daW" }, - { 0x0d700000, 0x04700000, "ldrbt", "daW" }, - { 0x0c500000, 0x04000000, "str", "daW" }, - { 0x0c500000, 0x04100000, "ldr", "daW" }, - { 0x0c500000, 0x04400000, "strb", "daW" }, - { 0x0c500000, 0x04500000, "ldrb", "daW" }, - { 0x0e1f0000, 0x080d0000, "stm", "YnWl" },/* separate out r13 base */ - { 0x0e1f0000, 0x081d0000, "ldm", "YnWl" },/* separate out r13 base */ - { 0x0e100000, 0x08000000, "stm", "XnWl" }, - { 0x0e100000, 0x08100000, "ldm", "XnWl" }, - { 0x0e1000f0, 0x00100090, "ldrb", "deW" }, - { 0x0e1000f0, 0x00000090, "strb", "deW" }, - { 0x0e1000f0, 0x001000d0, "ldrsb", "deW" }, - { 0x0e1000f0, 0x001000b0, "ldrh", "deW" }, - { 0x0e1000f0, 0x000000b0, "strh", "deW" }, - { 0x0e1000f0, 0x001000f0, "ldrsh", "deW" }, - { 0x0f200090, 0x00200090, "und", "x" }, /* Before data processing */ - { 0x0e1000d0, 0x000000d0, "und", "x" }, /* Before data processing */ - { 0x0ff00ff0, 0x01000090, "swp", "dmo" }, - { 0x0ff00ff0, 0x01400090, "swpb", "dmo" }, - { 0x0fbf0fff, 0x010f0000, "mrs", "dp" }, /* Before data processing */ - { 0x0fb0fff0, 0x0120f000, "msr", "pFm" },/* Before data processing */ - { 0x0fb0f000, 0x0320f000, "msr", "pF2" },/* Before data processing */ - { 0x0ffffff0, 0x012fff10, "bx", "m" }, - { 0x0fff0ff0, 0x016f0f10, "clz", "dm" }, - { 0x0ffffff0, 0x012fff30, "blx", "m" }, - { 0xfff000f0, 0xe1200070, "bkpt", "k" }, - { 0x0de00000, 0x00000000, "and", "Sdn2" }, - { 0x0de00000, 0x00200000, "eor", "Sdn2" }, - { 0x0de00000, 0x00400000, "sub", "Sdn2" }, - { 0x0de00000, 0x00600000, "rsb", "Sdn2" }, - { 0x0de00000, 0x00800000, "add", "Sdn2" }, - { 0x0de00000, 0x00a00000, "adc", "Sdn2" }, - { 0x0de00000, 0x00c00000, "sbc", "Sdn2" }, - { 0x0de00000, 0x00e00000, "rsc", "Sdn2" }, - { 0x0df00000, 0x01100000, "tst", "Dn2" }, - { 0x0df00000, 0x01300000, "teq", "Dn2" }, - { 0x0df00000, 0x01500000, "cmp", "Dn2" }, - { 0x0df00000, 0x01700000, "cmn", "Dn2" }, - { 0x0de00000, 0x01800000, "orr", "Sdn2" }, - { 0x0de00000, 0x01a00000, "mov", "Sd2" }, - { 0x0de00000, 0x01c00000, "bic", "Sdn2" }, - { 0x0de00000, 0x01e00000, "mvn", "Sd2" }, - { 0x0ff08f10, 0x0e000100, "adf", "PRfgh" }, - { 0x0ff08f10, 0x0e100100, "muf", "PRfgh" }, - { 0x0ff08f10, 0x0e200100, "suf", "PRfgh" }, - { 0x0ff08f10, 0x0e300100, "rsf", "PRfgh" }, - { 0x0ff08f10, 0x0e400100, "dvf", "PRfgh" }, - { 0x0ff08f10, 0x0e500100, "rdf", "PRfgh" }, - { 0x0ff08f10, 0x0e600100, "pow", "PRfgh" }, - { 0x0ff08f10, 0x0e700100, "rpw", "PRfgh" }, - { 0x0ff08f10, 0x0e800100, "rmf", "PRfgh" }, - { 0x0ff08f10, 0x0e900100, "fml", "PRfgh" }, - { 0x0ff08f10, 0x0ea00100, "fdv", "PRfgh" }, - { 0x0ff08f10, 0x0eb00100, "frd", "PRfgh" }, - { 0x0ff08f10, 0x0ec00100, "pol", "PRfgh" }, - { 0x0f008f10, 0x0e000100, "fpbop", "PRfgh" }, - { 0x0ff08f10, 0x0e008100, "mvf", "PRfh" }, - { 0x0ff08f10, 0x0e108100, "mnf", "PRfh" }, - { 0x0ff08f10, 0x0e208100, "abs", "PRfh" }, - { 0x0ff08f10, 0x0e308100, "rnd", "PRfh" }, - { 0x0ff08f10, 0x0e408100, "sqt", "PRfh" }, - { 0x0ff08f10, 0x0e508100, "log", "PRfh" }, - { 0x0ff08f10, 0x0e608100, "lgn", "PRfh" }, - { 0x0ff08f10, 0x0e708100, "exp", "PRfh" }, - { 0x0ff08f10, 0x0e808100, "sin", "PRfh" }, - { 0x0ff08f10, 0x0e908100, "cos", "PRfh" }, - { 0x0ff08f10, 0x0ea08100, "tan", "PRfh" }, - { 0x0ff08f10, 0x0eb08100, "asn", "PRfh" }, - { 0x0ff08f10, 0x0ec08100, "acs", "PRfh" }, - { 0x0ff08f10, 0x0ed08100, "atn", "PRfh" }, - { 0x0f008f10, 0x0e008100, "fpuop", "PRfh" }, - { 0x0e100f00, 0x0c000100, "stf", "QLv" }, - { 0x0e100f00, 0x0c100100, "ldf", "QLv" }, - { 0x0ff00f10, 0x0e000110, "flt", "PRgd" }, - { 0x0ff00f10, 0x0e100110, "fix", "PRdh" }, - { 0x0ff00f10, 0x0e200110, "wfs", "d" }, - { 0x0ff00f10, 0x0e300110, "rfs", "d" }, - { 0x0ff00f10, 0x0e400110, "wfc", "d" }, - { 0x0ff00f10, 0x0e500110, "rfc", "d" }, - { 0x0ff0ff10, 0x0e90f110, "cmf", "PRgh" }, - { 0x0ff0ff10, 0x0eb0f110, "cnf", "PRgh" }, - { 0x0ff0ff10, 0x0ed0f110, "cmfe", "PRgh" }, - { 0x0ff0ff10, 0x0ef0f110, "cnfe", "PRgh" }, - { 0xff100010, 0xfe000010, "mcr2", "#z" }, - { 0x0f100010, 0x0e000010, "mcr", "#z" }, - { 0xff100010, 0xfe100010, "mrc2", "#z" }, - { 0x0f100010, 0x0e100010, "mrc", "#z" }, - { 0xff000010, 0xfe000000, "cdp2", "#y" }, - { 0x0f000010, 0x0e000000, "cdp", "#y" }, - { 0xfe100090, 0xfc100000, "ldc2", "L#v" }, - { 0x0e100090, 0x0c100000, "ldc", "L#v" }, - { 0xfe100090, 0xfc000000, "stc2", "L#v" }, - { 0x0e100090, 0x0c000000, "stc", "L#v" }, - { 0xf550f000, 0xf550f000, "pld", "ne" }, - { 0x0ff00ff0, 0x01000050, "qaad", "dmn" }, - { 0x0ff00ff0, 0x01400050, "qdaad", "dmn" }, - { 0x0ff00ff0, 0x01600050, "qdsub", "dmn" }, - { 0x0ff00ff0, 0x01200050, "dsub", "dmn" }, - { 0x0ff000f0, 0x01000080, "smlabb", "nmsd" }, // d & n inverted!! - { 0x0ff000f0, 0x010000a0, "smlatb", "nmsd" }, // d & n inverted!! - { 0x0ff000f0, 0x010000c0, "smlabt", "nmsd" }, // d & n inverted!! - { 0x0ff000f0, 0x010000e0, "smlatt", "nmsd" }, // d & n inverted!! - { 0x0ff000f0, 0x01400080, "smlalbb","ndms" }, // d & n inverted!! - { 0x0ff000f0, 0x014000a0, "smlaltb","ndms" }, // d & n inverted!! - { 0x0ff000f0, 0x014000c0, "smlalbt","ndms" }, // d & n inverted!! - { 0x0ff000f0, 0x014000e0, "smlaltt","ndms" }, // d & n inverted!! - { 0x0ff000f0, 0x01200080, "smlawb", "nmsd" }, // d & n inverted!! - { 0x0ff0f0f0, 0x012000a0, "smulwb","nms" }, // d & n inverted!! - { 0x0ff000f0, 0x012000c0, "smlawt", "nmsd" }, // d & n inverted!! - { 0x0ff0f0f0, 0x012000e0, "smulwt","nms" }, // d & n inverted!! - { 0x0ff0f0f0, 0x01600080, "smulbb","nms" }, // d & n inverted!! - { 0x0ff0f0f0, 0x016000a0, "smultb","nms" }, // d & n inverted!! - { 0x0ff0f0f0, 0x016000c0, "smulbt","nms" }, // d & n inverted!! - { 0x0ff0f0f0, 0x016000e0, "smultt","nms" }, // d & n inverted!! - { 0x00000000, 0x00000000, NULL, NULL } -}; - -static char const arm32_insn_conditions[][4] = { - "eq", "ne", "cs", "cc", - "mi", "pl", "vs", "vc", - "hi", "ls", "ge", "lt", - "gt", "le", "", "nv" -}; - -static char const insn_block_transfers[][4] = { - "da", "ia", "db", "ib" -}; - -static char const insn_stack_block_transfers[][4] = { - "ed", "ea", "fd", "fa" -}; - -static char const op_shifts[][4] = { - "lsl", "lsr", "asr", "ror" -}; - -static char const insn_fpa_rounding[][2] = { - "", "p", "m", "z" -}; - -static char const insn_fpa_precision[][2] = { - "s", "d", "e", "p" -}; - -static char const insn_fpaconstants[][8] = { - "0.0", "1.0", "2.0", "3.0", - "4.0", "5.0", "0.5", "10.0" -}; - -#define insn_condition(x) arm32_insn_conditions[(x >> 28) & 0x0f] -#define insn_blktrans(x) insn_block_transfers[(x >> 23) & 3] -#define insn_stkblktrans(x) insn_stack_block_transfers[(x >> 23) & 3] -#define op2_shift(x) op_shifts[(x >> 5) & 3] -#define insn_fparnd(x) insn_fpa_rounding[(x >> 5) & 0x03] -#define insn_fpaprec(x) insn_fpa_precision[(((x >> 18) & 2)|(x >> 7)) & 1] -#define insn_fpaprect(x) insn_fpa_precision[(((x >> 21) & 2)|(x >> 15)) & 1] -#define insn_fpaimm(x) insn_fpaconstants[x & 0x07] - -/* Local prototypes */ -static void disasm_register_shift(const disasm_interface_t *di, u_int insn); -static void disasm_print_reglist(const disasm_interface_t *di, u_int insn); -static void disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, - u_int loc); -static void disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, - u_int loc); -static void disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, - u_int loc); -static u_int disassemble_readword(u_int address); -static void disassemble_printaddr(u_int address); - -u_int -disasm(const disasm_interface_t *di, u_int loc, int altfmt) -{ - const struct arm32_insn *i_ptr = &arm32_i[0]; - - u_int insn; - int matchp; - int branch; - char* f_ptr; - int fmt; - - fmt = 0; - matchp = 0; - insn = di->di_readword(loc); - -/* di->di_printf("loc=%08x insn=%08x : ", loc, insn);*/ - - while (i_ptr->name) { - if ((insn & i_ptr->mask) == i_ptr->pattern) { - matchp = 1; - break; - } - i_ptr++; - } - - if (!matchp) { - di->di_printf("und%s\t%08x\n", insn_condition(insn), insn); - return(loc + INSN_SIZE); - } - - /* If instruction forces condition code, don't print it. */ - if ((i_ptr->mask & 0xf0000000) == 0xf0000000) - di->di_printf("%s", i_ptr->name); - else - di->di_printf("%s%s", i_ptr->name, insn_condition(insn)); - - f_ptr = i_ptr->format; - - /* Insert tab if there are no instruction modifiers */ - - if (*(f_ptr) < 'A' || *(f_ptr) > 'Z') { - ++fmt; - di->di_printf("\t"); - } - - while (*f_ptr) { - switch (*f_ptr) { - /* 2 - print Operand 2 of a data processing instruction */ - case '2': - if (insn & 0x02000000) { - int rotate= ((insn >> 7) & 0x1e); - - di->di_printf("#0x%08x", - (insn & 0xff) << (32 - rotate) | - (insn & 0xff) >> rotate); - } else { - disasm_register_shift(di, insn); - } - break; - /* d - destination register (bits 12-15) */ - case 'd': - di->di_printf("r%d", ((insn >> 12) & 0x0f)); - break; - /* D - insert 'p' if Rd is R15 */ - case 'D': - if (((insn >> 12) & 0x0f) == 15) - di->di_printf("p"); - break; - /* n - n register (bits 16-19) */ - case 'n': - di->di_printf("r%d", ((insn >> 16) & 0x0f)); - break; - /* s - s register (bits 8-11) */ - case 's': - di->di_printf("r%d", ((insn >> 8) & 0x0f)); - break; - /* o - indirect register rn (bits 16-19) (used by swap) */ - case 'o': - di->di_printf("[r%d]", ((insn >> 16) & 0x0f)); - break; - /* m - m register (bits 0-4) */ - case 'm': - di->di_printf("r%d", ((insn >> 0) & 0x0f)); - break; - /* a - address operand of ldr/str instruction */ - case 'a': - disasm_insn_ldrstr(di, insn, loc); - break; - /* e - address operand of ldrh/strh instruction */ - case 'e': - disasm_insn_ldrhstrh(di, insn, loc); - break; - /* l - register list for ldm/stm instruction */ - case 'l': - disasm_print_reglist(di, insn); - break; - /* f - 1st fp operand (register) (bits 12-14) */ - case 'f': - di->di_printf("f%d", (insn >> 12) & 7); - break; - /* g - 2nd fp operand (register) (bits 16-18) */ - case 'g': - di->di_printf("f%d", (insn >> 16) & 7); - break; - /* h - 3rd fp operand (register/immediate) (bits 0-4) */ - case 'h': - if (insn & (1 << 3)) - di->di_printf("#%s", insn_fpaimm(insn)); - else - di->di_printf("f%d", insn & 7); - break; - /* b - branch address */ - case 'b': - branch = ((insn << 2) & 0x03ffffff); - if (branch & 0x02000000) - branch |= 0xfc000000; - di->di_printaddr(loc + 8 + branch); - break; - /* t - blx address */ - case 't': - branch = ((insn << 2) & 0x03ffffff) | - (insn >> 23 & 0x00000002); - if (branch & 0x02000000) - branch |= 0xfc000000; - di->di_printaddr(loc + 8 + branch); - break; - /* X - block transfer type */ - case 'X': - di->di_printf("%s", insn_blktrans(insn)); - break; - /* Y - block transfer type (r13 base) */ - case 'Y': - di->di_printf("%s", insn_stkblktrans(insn)); - break; - /* c - comment field bits(0-23) */ - case 'c': - di->di_printf("0x%08x", (insn & 0x00ffffff)); - break; - /* k - breakpoint comment (bits 0-3, 8-19) */ - case 'k': - di->di_printf("0x%04x", - (insn & 0x000fff00) >> 4 | (insn & 0x0000000f)); - break; - /* p - saved or current status register */ - case 'p': - if (insn & 0x00400000) - di->di_printf("spsr"); - else - di->di_printf("cpsr"); - break; - /* F - PSR transfer fields */ - case 'F': - di->di_printf("_"); - if (insn & (1 << 16)) - di->di_printf("c"); - if (insn & (1 << 17)) - di->di_printf("x"); - if (insn & (1 << 18)) - di->di_printf("s"); - if (insn & (1 << 19)) - di->di_printf("f"); - break; - /* B - byte transfer flag */ - case 'B': - if (insn & 0x00400000) - di->di_printf("b"); - break; - /* L - co-processor transfer size */ - case 'L': - if (insn & (1 << 22)) - di->di_printf("l"); - break; - /* S - set status flag */ - case 'S': - if (insn & 0x00100000) - di->di_printf("s"); - break; - /* P - fp precision */ - case 'P': - di->di_printf("%s", insn_fpaprec(insn)); - break; - /* Q - fp precision (for ldf/stf) */ - case 'Q': - break; - /* R - fp rounding */ - case 'R': - di->di_printf("%s", insn_fparnd(insn)); - break; - /* W - writeback flag */ - case 'W': - if (insn & (1 << 21)) - di->di_printf("!"); - break; - /* # - co-processor number */ - case '#': - di->di_printf("p%d", (insn >> 8) & 0x0f); - break; - /* v - co-processor data transfer registers+addressing mode */ - case 'v': - disasm_insn_ldcstc(di, insn, loc); - break; - /* x - instruction in hex */ - case 'x': - di->di_printf("0x%08x", insn); - break; - /* y - co-processor data processing registers */ - case 'y': - di->di_printf("%d, ", (insn >> 20) & 0x0f); - - di->di_printf("c%d, c%d, c%d", (insn >> 12) & 0x0f, - (insn >> 16) & 0x0f, insn & 0x0f); - - di->di_printf(", %d", (insn >> 5) & 0x07); - break; - /* z - co-processor register transfer registers */ - case 'z': - di->di_printf("%d, ", (insn >> 21) & 0x07); - di->di_printf("r%d, c%d, c%d, %d", - (insn >> 12) & 0x0f, (insn >> 16) & 0x0f, - insn & 0x0f, (insn >> 5) & 0x07); - -/* if (((insn >> 5) & 0x07) != 0) - di->di_printf(", %d", (insn >> 5) & 0x07);*/ - break; - default: - di->di_printf("[%c - unknown]", *f_ptr); - break; - } - if (*(f_ptr+1) >= 'A' && *(f_ptr+1) <= 'Z') - ++f_ptr; - else if (*(++f_ptr)) { - ++fmt; - if (fmt == 1) - di->di_printf("\t"); - else - di->di_printf(", "); - } - }; - - di->di_printf("\n"); - - return(loc + INSN_SIZE); -} - - -static void -disasm_register_shift(const disasm_interface_t *di, u_int insn) -{ - di->di_printf("r%d", (insn & 0x0f)); - if ((insn & 0x00000ff0) == 0) - ; - else if ((insn & 0x00000ff0) == 0x00000060) - di->di_printf(", rrx"); - else { - if (insn & 0x10) - di->di_printf(", %s r%d", op2_shift(insn), - (insn >> 8) & 0x0f); - else - di->di_printf(", %s #%d", op2_shift(insn), - (insn >> 7) & 0x1f); - } -} - - -static void -disasm_print_reglist(const disasm_interface_t *di, u_int insn) -{ - int loop; - int start; - int comma; - - di->di_printf("{"); - start = -1; - comma = 0; - - for (loop = 0; loop < 17; ++loop) { - if (start != -1) { - if (loop == 16 || !(insn & (1 << loop))) { - if (comma) - di->di_printf(", "); - else - comma = 1; - if (start == loop - 1) - di->di_printf("r%d", start); - else - di->di_printf("r%d-r%d", start, loop - 1); - start = -1; - } - } else { - if (insn & (1 << loop)) - start = loop; - } - } - di->di_printf("}"); - - if (insn & (1 << 22)) - di->di_printf("^"); -} - -static void -disasm_insn_ldrstr(const disasm_interface_t *di, u_int insn, u_int loc) -{ - int offset; - - offset = insn & 0xfff; - if ((insn & 0x032f0000) == 0x010f0000) { - /* rA = pc, immediate index */ - if (insn & 0x00800000) - loc += offset; - else - loc -= offset; - di->di_printaddr(loc + 8); - } else { - di->di_printf("[r%d", (insn >> 16) & 0x0f); - if ((insn & 0x03000fff) != 0x01000000) { - di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); - if (!(insn & 0x00800000)) - di->di_printf("-"); - if (insn & (1 << 25)) - disasm_register_shift(di, insn); - else - di->di_printf("#0x%03x", offset); - } - if (insn & (1 << 24)) - di->di_printf("]"); - } -} - -static void -disasm_insn_ldrhstrh(const disasm_interface_t *di, u_int insn, u_int loc) -{ - int offset; - - offset = ((insn & 0xf00) >> 4) | (insn & 0xf); - if ((insn & 0x004f0000) == 0x004f0000) { - /* rA = pc, immediate index */ - if (insn & 0x00800000) - loc += offset; - else - loc -= offset; - di->di_printaddr(loc + 8); - } else { - di->di_printf("[r%d", (insn >> 16) & 0x0f); - if ((insn & 0x01400f0f) != 0x01400000) { - di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); - if (!(insn & 0x00800000)) - di->di_printf("-"); - if (insn & (1 << 22)) - di->di_printf("#0x%02x", offset); - else - di->di_printf("r%d", (insn & 0x0f)); - } - if (insn & (1 << 24)) - di->di_printf("]"); - } -} - -static void -disasm_insn_ldcstc(const disasm_interface_t *di, u_int insn, u_int loc) -{ - if (((insn >> 8) & 0xf) == 1) - di->di_printf("f%d, ", (insn >> 12) & 0x07); - else - di->di_printf("c%d, ", (insn >> 12) & 0x0f); - - di->di_printf("[r%d", (insn >> 16) & 0x0f); - - di->di_printf("%s, ", (insn & (1 << 24)) ? "" : "]"); - - if (!(insn & (1 << 23))) - di->di_printf("-"); - - di->di_printf("#0x%03x", (insn & 0xff) << 2); - - if (insn & (1 << 24)) - di->di_printf("]"); - - if (insn & (1 << 21)) - di->di_printf("!"); -} - -static u_int -disassemble_readword(u_int address) -{ - return(*((u_int *)address)); -} - -static void -disassemble_printaddr(u_int address) -{ - printf("0x%08x", address); -} - -static const disasm_interface_t disassemble_di = { - disassemble_readword, disassemble_printaddr, printf -}; - -void -disassemble(u_int address) -{ - - (void)disasm(&disassemble_di, address, 0); -} - -/* End of disassem.c */ diff --git a/libpixelflinger/codeflinger/disassem.h b/libpixelflinger/codeflinger/disassem.h deleted file mode 100644 index 02747cd068f474d4b18402ccd8527ce28a45fd4c..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/disassem.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $NetBSD: disassem.h,v 1.4 2001/03/04 04:15:58 matt Exp $ */ - -/*- - * Copyright (c) 1997 Mark Brinicombe. - * Copyright (c) 1997 Causality Limited. - * - * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Mark Brinicombe. - * 4. The name of the company nor the name of the author may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * Define the interface structure required by the disassembler. - * - * $FreeBSD: /repoman/r/ncvs/src/sys/arm/include/disassem.h,v 1.2 2005/01/05 21:58:48 imp Exp $ - */ - -#ifndef ANDROID_MACHINE_DISASSEM_H -#define ANDROID_MACHINE_DISASSEM_H - -#include <sys/types.h> - -#if __cplusplus -extern "C" { -#endif - -typedef struct { - u_int (*di_readword)(u_int); - void (*di_printaddr)(u_int); - void (*di_printf)(const char *, ...); -} disasm_interface_t; - -/* Prototypes for callable functions */ - -u_int disasm(const disasm_interface_t *, u_int, int); -void disassemble(u_int); - -#if __cplusplus -} -#endif - -#endif /* !ANDROID_MACHINE_DISASSEM_H */ diff --git a/libpixelflinger/codeflinger/load_store.cpp b/libpixelflinger/codeflinger/load_store.cpp deleted file mode 100644 index 93c5825797275eafb5cff63eadc0b1bd5f35dac5..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/load_store.cpp +++ /dev/null @@ -1,378 +0,0 @@ -/* libs/pixelflinger/codeflinger/load_store.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <assert.h> -#include <stdio.h> -#include <cutils/log.h> - -#include "codeflinger/GGLAssembler.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -void GGLAssembler::store(const pointer_t& addr, const pixel_t& s, uint32_t flags) -{ - const int bits = addr.size; - const int inc = (flags & WRITE_BACK)?1:0; - switch (bits) { - case 32: - if (inc) STR(AL, s.reg, addr.reg, immed12_post(4)); - else STR(AL, s.reg, addr.reg); - break; - case 24: - // 24 bits formats are a little special and used only for RGB - // 0x00BBGGRR is unpacked as R,G,B - STRB(AL, s.reg, addr.reg, immed12_pre(0)); - MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8)); - STRB(AL, s.reg, addr.reg, immed12_pre(1)); - MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 8)); - STRB(AL, s.reg, addr.reg, immed12_pre(2)); - if (!(s.flags & CORRUPTIBLE)) { - MOV(AL, 0, s.reg, reg_imm(s.reg, ROR, 16)); - } - if (inc) - ADD(AL, 0, addr.reg, addr.reg, imm(3)); - break; - case 16: - if (inc) STRH(AL, s.reg, addr.reg, immed8_post(2)); - else STRH(AL, s.reg, addr.reg); - break; - case 8: - if (inc) STRB(AL, s.reg, addr.reg, immed12_post(1)); - else STRB(AL, s.reg, addr.reg); - break; - } -} - -void GGLAssembler::load(const pointer_t& addr, const pixel_t& s, uint32_t flags) -{ - Scratch scratches(registerFile()); - int s0; - - const int bits = addr.size; - const int inc = (flags & WRITE_BACK)?1:0; - switch (bits) { - case 32: - if (inc) LDR(AL, s.reg, addr.reg, immed12_post(4)); - else LDR(AL, s.reg, addr.reg); - break; - case 24: - // 24 bits formats are a little special and used only for RGB - // R,G,B is packed as 0x00BBGGRR - s0 = scratches.obtain(); - if (s.reg != addr.reg) { - LDRB(AL, s.reg, addr.reg, immed12_pre(0)); // R - LDRB(AL, s0, addr.reg, immed12_pre(1)); // G - ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 8)); - LDRB(AL, s0, addr.reg, immed12_pre(2)); // B - ORR(AL, 0, s.reg, s.reg, reg_imm(s0, LSL, 16)); - } else { - int s1 = scratches.obtain(); - LDRB(AL, s1, addr.reg, immed12_pre(0)); // R - LDRB(AL, s0, addr.reg, immed12_pre(1)); // G - ORR(AL, 0, s1, s1, reg_imm(s0, LSL, 8)); - LDRB(AL, s0, addr.reg, immed12_pre(2)); // B - ORR(AL, 0, s.reg, s1, reg_imm(s0, LSL, 16)); - } - if (inc) - ADD(AL, 0, addr.reg, addr.reg, imm(3)); - break; - case 16: - if (inc) LDRH(AL, s.reg, addr.reg, immed8_post(2)); - else LDRH(AL, s.reg, addr.reg); - break; - case 8: - if (inc) LDRB(AL, s.reg, addr.reg, immed12_post(1)); - else LDRB(AL, s.reg, addr.reg); - break; - } -} - -void GGLAssembler::extract(integer_t& d, int s, int h, int l, int bits) -{ - const int maskLen = h-l; - - assert(maskLen<=8); - assert(h); - - if (h != bits) { - const int mask = ((1<<maskLen)-1) << l; - if (isValidImmediate(mask)) { - AND(AL, 0, d.reg, s, imm(mask)); // component = packed & mask; - } else if (isValidImmediate(~mask)) { - BIC(AL, 0, d.reg, s, imm(~mask)); // component = packed & mask; - } else { - MOV(AL, 0, d.reg, reg_imm(s, LSL, 32-h)); - l += 32-h; - h = 32; - } - s = d.reg; - } - - if (l) { - MOV(AL, 0, d.reg, reg_imm(s, LSR, l)); // component = packed >> l; - s = d.reg; - } - - if (s != d.reg) { - MOV(AL, 0, d.reg, s); - } - - d.s = maskLen; -} - -void GGLAssembler::extract(integer_t& d, const pixel_t& s, int component) -{ - extract(d, s.reg, - s.format.c[component].h, - s.format.c[component].l, - s.size()); -} - -void GGLAssembler::extract(component_t& d, const pixel_t& s, int component) -{ - integer_t r(d.reg, 32, d.flags); - extract(r, s.reg, - s.format.c[component].h, - s.format.c[component].l, - s.size()); - d = component_t(r); -} - - -void GGLAssembler::expand(integer_t& d, const component_t& s, int dbits) -{ - if (s.l || (s.flags & CLEAR_HI)) { - extract(d, s.reg, s.h, s.l, 32); - expand(d, d, dbits); - } else { - expand(d, integer_t(s.reg, s.size(), s.flags), dbits); - } -} - -void GGLAssembler::expand(component_t& d, const component_t& s, int dbits) -{ - integer_t r(d.reg, 32, d.flags); - expand(r, s, dbits); - d = component_t(r); -} - -void GGLAssembler::expand(integer_t& dst, const integer_t& src, int dbits) -{ - assert(src.size()); - - int sbits = src.size(); - int s = src.reg; - int d = dst.reg; - - // be sure to set 'dst' after we read 'src' as they may be identical - dst.s = dbits; - dst.flags = 0; - - if (dbits<=sbits) { - if (s != d) { - MOV(AL, 0, d, s); - } - return; - } - - if (sbits == 1) { - RSB(AL, 0, d, s, reg_imm(s, LSL, dbits)); - // d = (s<<dbits) - s; - return; - } - - if (dbits % sbits) { - MOV(AL, 0, d, reg_imm(s, LSL, dbits-sbits)); - // d = s << (dbits-sbits); - dbits -= sbits; - do { - ORR(AL, 0, d, d, reg_imm(d, LSR, sbits)); - // d |= d >> sbits; - dbits -= sbits; - sbits *= 2; - } while(dbits>0); - return; - } - - dbits -= sbits; - do { - ORR(AL, 0, d, s, reg_imm(s, LSL, sbits)); - // d |= d<<sbits; - s = d; - dbits -= sbits; - if (sbits*2 < dbits) { - sbits *= 2; - } - } while(dbits>0); -} - -void GGLAssembler::downshift( - pixel_t& d, int component, component_t s, const reg_t& dither) -{ - const needs_t& needs = mBuilderContext.needs; - Scratch scratches(registerFile()); - - int sh = s.h; - int sl = s.l; - int maskHiBits = (sh!=32) ? ((s.flags & CLEAR_HI)?1:0) : 0; - int maskLoBits = (sl!=0) ? ((s.flags & CLEAR_LO)?1:0) : 0; - int sbits = sh - sl; - - int dh = d.format.c[component].h; - int dl = d.format.c[component].l; - int dbits = dh - dl; - int dithering = 0; - - LOGE_IF(sbits<dbits, "sbits (%d) < dbits (%d) in downshift", sbits, dbits); - - if (sbits>dbits) { - // see if we need to dither - dithering = mDithering; - } - - int ireg = d.reg; - if (!(d.flags & FIRST)) { - if (s.flags & CORRUPTIBLE) { - ireg = s.reg; - } else { - ireg = scratches.obtain(); - } - } - d.flags &= ~FIRST; - - if (maskHiBits) { - // we need to mask the high bits (and possibly the lowbits too) - // and we might be able to use immediate mask. - if (!dithering) { - // we don't do this if we only have maskLoBits because we can - // do it more efficiently below (in the case where dl=0) - const int offset = sh - dbits; - if (dbits<=8 && offset >= 0) { - const uint32_t mask = ((1<<dbits)-1) << offset; - if (isValidImmediate(mask) || isValidImmediate(~mask)) { - build_and_immediate(ireg, s.reg, mask, 32); - sl = offset; - s.reg = ireg; - sbits = dbits; - maskLoBits = maskHiBits = 0; - } - } - } else { - // in the dithering case though, we need to preserve the lower bits - const uint32_t mask = ((1<<sbits)-1) << sl; - if (isValidImmediate(mask) || isValidImmediate(~mask)) { - build_and_immediate(ireg, s.reg, mask, 32); - s.reg = ireg; - maskLoBits = maskHiBits = 0; - } - } - } - - // XXX: we could special case (maskHiBits & !maskLoBits) - // like we do for maskLoBits below, but it happens very rarely - // that we have maskHiBits only and the conditions necessary to lead - // to better code (like doing d |= s << 24) - - if (maskHiBits) { - MOV(AL, 0, ireg, reg_imm(s.reg, LSL, 32-sh)); - sl += 32-sh; - sh = 32; - s.reg = ireg; - maskHiBits = 0; - } - - // Downsampling should be performed as follows: - // V * ((1<<dbits)-1) / ((1<<sbits)-1) - // V * [(1<<dbits)/((1<<sbits)-1) - 1/((1<<sbits)-1)] - // V * [1/((1<<sbits)-1)>>dbits - 1/((1<<sbits)-1)] - // V/((1<<(sbits-dbits))-(1>>dbits)) - (V>>sbits)/((1<<sbits)-1)>>sbits - // V/((1<<(sbits-dbits))-(1>>dbits)) - (V>>sbits)/(1-(1>>sbits)) - // - // By approximating (1>>dbits) and (1>>sbits) to 0: - // - // V>>(sbits-dbits) - V>>sbits - // - // A good approximation is V>>(sbits-dbits), - // but better one (needed for dithering) is: - // - // (V>>(sbits-dbits)<<sbits - V)>>sbits - // (V<<dbits - V)>>sbits - // (V - V>>dbits)>>(sbits-dbits) - - // Dithering is done here - if (dithering) { - comment("dithering"); - if (sl) { - MOV(AL, 0, ireg, reg_imm(s.reg, LSR, sl)); - sh -= sl; - sl = 0; - s.reg = ireg; - } - // scaling (V-V>>dbits) - SUB(AL, 0, ireg, s.reg, reg_imm(s.reg, LSR, dbits)); - const int shift = (GGL_DITHER_BITS - (sbits-dbits)); - if (shift>0) ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSR, shift)); - else if (shift<0) ADD(AL, 0, ireg, ireg, reg_imm(dither.reg, LSL,-shift)); - else ADD(AL, 0, ireg, ireg, dither.reg); - s.reg = ireg; - } - - if ((maskLoBits|dithering) && (sh > dbits)) { - int shift = sh-dbits; - if (dl) { - MOV(AL, 0, ireg, reg_imm(s.reg, LSR, shift)); - if (ireg == d.reg) { - MOV(AL, 0, d.reg, reg_imm(ireg, LSL, dl)); - } else { - ORR(AL, 0, d.reg, d.reg, reg_imm(ireg, LSL, dl)); - } - } else { - if (ireg == d.reg) { - MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift)); - } else { - ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift)); - } - } - } else { - int shift = sh-dh; - if (shift>0) { - if (ireg == d.reg) { - MOV(AL, 0, d.reg, reg_imm(s.reg, LSR, shift)); - } else { - ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSR, shift)); - } - } else if (shift<0) { - if (ireg == d.reg) { - MOV(AL, 0, d.reg, reg_imm(s.reg, LSL, -shift)); - } else { - ORR(AL, 0, d.reg, d.reg, reg_imm(s.reg, LSL, -shift)); - } - } else { - if (ireg == d.reg) { - if (s.reg != d.reg) { - MOV(AL, 0, d.reg, s.reg); - } - } else { - ORR(AL, 0, d.reg, d.reg, s.reg); - } - } - } -} - -}; // namespace android diff --git a/libpixelflinger/codeflinger/texturing.cpp b/libpixelflinger/codeflinger/texturing.cpp deleted file mode 100644 index 90e658407bfa0d8b4ced41f1faa92614dc331756..0000000000000000000000000000000000000000 --- a/libpixelflinger/codeflinger/texturing.cpp +++ /dev/null @@ -1,1251 +0,0 @@ -/* libs/pixelflinger/codeflinger/texturing.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <assert.h> -#include <stdint.h> -#include <stdlib.h> -#include <stdio.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include "codeflinger/GGLAssembler.h" - - -namespace android { - -// --------------------------------------------------------------------------- - -// iterators are initialized like this: -// (intToFixedCenter(x) * dx)>>16 + x0 -// ((x<<16 + 0x8000) * dx)>>16 + x0 -// ((x<<16)*dx + (0x8000*dx))>>16 + x0 -// ( (x*dx) + dx>>1 ) + x0 -// (x*dx) + (dx>>1 + x0) - -void GGLAssembler::init_iterated_color(fragment_parts_t& parts, const reg_t& x) -{ - context_t const* c = mBuilderContext.c; - const needs_t& needs = mBuilderContext.needs; - - if (mSmooth) { - // NOTE: we could take this case in the mDithering + !mSmooth case, - // but this would use up to 4 more registers for the color components - // for only a little added quality. - // Currently, this causes the system to run out of registers in - // some case (see issue #719496) - - comment("compute initial iterated color (smooth and/or dither case)"); - - parts.iterated_packed = 0; - parts.packed = 0; - - // 0x1: color component - // 0x2: iterators - const int optReload = mOptLevel >> 1; - if (optReload >= 3) parts.reload = 0; // reload nothing - else if (optReload == 2) parts.reload = 2; // reload iterators - else if (optReload == 1) parts.reload = 1; // reload colors - else if (optReload <= 0) parts.reload = 3; // reload both - - if (!mSmooth) { - // we're not smoothing (just dithering), we never have to - // reload the iterators - parts.reload &= ~2; - } - - Scratch scratches(registerFile()); - const int t0 = (parts.reload & 1) ? scratches.obtain() : 0; - const int t1 = (parts.reload & 2) ? scratches.obtain() : 0; - for (int i=0 ; i<4 ; i++) { - if (!mInfo[i].iterated) - continue; - - // this component exists in the destination and is not replaced - // by a texture unit. - const int c = (parts.reload & 1) ? t0 : obtainReg(); - if (i==0) CONTEXT_LOAD(c, iterators.ydady); - if (i==1) CONTEXT_LOAD(c, iterators.ydrdy); - if (i==2) CONTEXT_LOAD(c, iterators.ydgdy); - if (i==3) CONTEXT_LOAD(c, iterators.ydbdy); - parts.argb[i].reg = c; - - if (mInfo[i].smooth) { - parts.argb_dx[i].reg = (parts.reload & 2) ? t1 : obtainReg(); - const int dvdx = parts.argb_dx[i].reg; - CONTEXT_LOAD(dvdx, generated_vars.argb[i].dx); - MLA(AL, 0, c, x.reg, dvdx, c); - - // adjust the color iterator to make sure it won't overflow - if (!mAA) { - // this is not needed when we're using anti-aliasing - // because we will (have to) clamp the components - // anyway. - int end = scratches.obtain(); - MOV(AL, 0, end, reg_imm(parts.count.reg, LSR, 16)); - MLA(AL, 1, end, dvdx, end, c); - SUB(MI, 0, c, c, end); - BIC(AL, 0, c, c, reg_imm(c, ASR, 31)); - scratches.recycle(end); - } - } - - if (parts.reload & 1) { - CONTEXT_STORE(c, generated_vars.argb[i].c); - } - } - } else { - // We're not smoothed, so we can - // just use a packed version of the color and extract the - // components as needed (or not at all if we don't blend) - - // figure out if we need the iterated color - int load = 0; - for (int i=0 ; i<4 ; i++) { - component_info_t& info = mInfo[i]; - if ((info.inDest || info.needed) && !info.replaced) - load |= 1; - } - - parts.iterated_packed = 1; - parts.packed = (!mTextureMachine.mask && !mBlending - && !mFog && !mDithering); - parts.reload = 0; - if (load || parts.packed) { - if (mBlending || mDithering || mInfo[GGLFormat::ALPHA].needed) { - comment("load initial iterated color (8888 packed)"); - parts.iterated.setTo(obtainReg(), - &(c->formats[GGL_PIXEL_FORMAT_RGBA_8888])); - CONTEXT_LOAD(parts.iterated.reg, packed8888); - } else { - comment("load initial iterated color (dest format packed)"); - - parts.iterated.setTo(obtainReg(), &mCbFormat); - - // pre-mask the iterated color - const int bits = parts.iterated.size(); - const uint32_t size = ((bits>=32) ? 0 : (1LU << bits)) - 1; - uint32_t mask = 0; - if (mMasking) { - for (int i=0 ; i<4 ; i++) { - const int component_mask = 1<<i; - const int h = parts.iterated.format.c[i].h; - const int l = parts.iterated.format.c[i].l; - if (h && (!(mMasking & component_mask))) { - mask |= ((1<<(h-l))-1) << l; - } - } - } - - if (mMasking && ((mask & size)==0)) { - // none of the components are present in the mask - } else { - CONTEXT_LOAD(parts.iterated.reg, packed); - if (mCbFormat.size == 1) { - AND(AL, 0, parts.iterated.reg, - parts.iterated.reg, imm(0xFF)); - } else if (mCbFormat.size == 2) { - MOV(AL, 0, parts.iterated.reg, - reg_imm(parts.iterated.reg, LSR, 16)); - } - } - - // pre-mask the iterated color - if (mMasking) { - build_and_immediate(parts.iterated.reg, parts.iterated.reg, - mask, bits); - } - } - } - } -} - -void GGLAssembler::build_iterated_color( - component_t& fragment, - const fragment_parts_t& parts, - int component, - Scratch& regs) -{ - fragment.setTo( regs.obtain(), 0, 32, CORRUPTIBLE); - - if (!mInfo[component].iterated) - return; - - if (parts.iterated_packed) { - // iterated colors are packed, extract the one we need - extract(fragment, parts.iterated, component); - } else { - fragment.h = GGL_COLOR_BITS; - fragment.l = GGL_COLOR_BITS - 8; - fragment.flags |= CLEAR_LO; - // iterated colors are held in their own register, - // (smooth and/or dithering case) - if (parts.reload==3) { - // this implies mSmooth - Scratch scratches(registerFile()); - int dx = scratches.obtain(); - CONTEXT_LOAD(fragment.reg, generated_vars.argb[component].c); - CONTEXT_LOAD(dx, generated_vars.argb[component].dx); - ADD(AL, 0, dx, fragment.reg, dx); - CONTEXT_STORE(dx, generated_vars.argb[component].c); - } else if (parts.reload & 1) { - CONTEXT_LOAD(fragment.reg, generated_vars.argb[component].c); - } else { - // we don't reload, so simply rename the register and mark as - // non CORRUPTIBLE so that the texture env or blending code - // won't modify this (renamed) register - regs.recycle(fragment.reg); - fragment.reg = parts.argb[component].reg; - fragment.flags &= ~CORRUPTIBLE; - } - if (mInfo[component].smooth && mAA) { - // when using smooth shading AND anti-aliasing, we need to clamp - // the iterators because there is always an extra pixel on the - // edges, which most of the time will cause an overflow - // (since technically its outside of the domain). - BIC(AL, 0, fragment.reg, fragment.reg, - reg_imm(fragment.reg, ASR, 31)); - component_sat(fragment); - } - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::decodeLogicOpNeeds(const needs_t& needs) -{ - // gather some informations about the components we need to process... - const int opcode = GGL_READ_NEEDS(LOGIC_OP, needs.n) | GGL_CLEAR; - switch(opcode) { - case GGL_COPY: - mLogicOp = 0; - break; - case GGL_CLEAR: - case GGL_SET: - mLogicOp = LOGIC_OP; - break; - case GGL_AND: - case GGL_AND_REVERSE: - case GGL_AND_INVERTED: - case GGL_XOR: - case GGL_OR: - case GGL_NOR: - case GGL_EQUIV: - case GGL_OR_REVERSE: - case GGL_OR_INVERTED: - case GGL_NAND: - mLogicOp = LOGIC_OP|LOGIC_OP_SRC|LOGIC_OP_DST; - break; - case GGL_NOOP: - case GGL_INVERT: - mLogicOp = LOGIC_OP|LOGIC_OP_DST; - break; - case GGL_COPY_INVERTED: - mLogicOp = LOGIC_OP|LOGIC_OP_SRC; - break; - }; -} - -void GGLAssembler::decodeTMUNeeds(const needs_t& needs, context_t const* c) -{ - uint8_t replaced=0; - mTextureMachine.mask = 0; - mTextureMachine.activeUnits = 0; - for (int i=GGL_TEXTURE_UNIT_COUNT-1 ; i>=0 ; i--) { - texture_unit_t& tmu = mTextureMachine.tmu[i]; - if (replaced == 0xF) { - // all components are replaced, skip this TMU. - tmu.format_idx = 0; - tmu.mask = 0; - tmu.replaced = replaced; - continue; - } - tmu.format_idx = GGL_READ_NEEDS(T_FORMAT, needs.t[i]); - tmu.format = c->formats[tmu.format_idx]; - tmu.bits = tmu.format.size*8; - tmu.swrap = GGL_READ_NEEDS(T_S_WRAP, needs.t[i]); - tmu.twrap = GGL_READ_NEEDS(T_T_WRAP, needs.t[i]); - tmu.env = ggl_needs_to_env(GGL_READ_NEEDS(T_ENV, needs.t[i])); - tmu.pot = GGL_READ_NEEDS(T_POT, needs.t[i]); - tmu.linear = GGL_READ_NEEDS(T_LINEAR, needs.t[i]) - && tmu.format.size!=3; // XXX: only 8, 16 and 32 modes for now - - // 5551 linear filtering is not supported - if (tmu.format_idx == GGL_PIXEL_FORMAT_RGBA_5551) - tmu.linear = 0; - - tmu.mask = 0; - tmu.replaced = replaced; - - if (tmu.format_idx) { - mTextureMachine.activeUnits++; - if (tmu.format.c[0].h) tmu.mask |= 0x1; - if (tmu.format.c[1].h) tmu.mask |= 0x2; - if (tmu.format.c[2].h) tmu.mask |= 0x4; - if (tmu.format.c[3].h) tmu.mask |= 0x8; - if (tmu.env == GGL_REPLACE) { - replaced |= tmu.mask; - } else if (tmu.env == GGL_DECAL) { - if (!tmu.format.c[GGLFormat::ALPHA].h) { - // if we don't have alpha, decal does nothing - tmu.mask = 0; - } else { - // decal always ignores At - tmu.mask &= ~(1<<GGLFormat::ALPHA); - } - } - } - mTextureMachine.mask |= tmu.mask; - //printf("%d: mask=%08lx, replaced=%08lx\n", - // i, int(tmu.mask), int(tmu.replaced)); - } - mTextureMachine.replaced = replaced; - mTextureMachine.directTexture = 0; - //printf("replaced=%08lx\n", mTextureMachine.replaced); -} - - -void GGLAssembler::init_textures( - tex_coord_t* coords, - const reg_t& x, const reg_t& y) -{ - context_t const* c = mBuilderContext.c; - const needs_t& needs = mBuilderContext.needs; - int Rctx = mBuilderContext.Rctx; - int Rx = x.reg; - int Ry = y.reg; - - if (mTextureMachine.mask) { - comment("compute texture coordinates"); - } - - // init texture coordinates for each tmu - const int cb_format_idx = GGL_READ_NEEDS(CB_FORMAT, needs.n); - const bool multiTexture = mTextureMachine.activeUnits > 1; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) { - const texture_unit_t& tmu = mTextureMachine.tmu[i]; - if (tmu.format_idx == 0) - continue; - if ((tmu.swrap == GGL_NEEDS_WRAP_11) && - (tmu.twrap == GGL_NEEDS_WRAP_11)) - { - // 1:1 texture - pointer_t& txPtr = coords[i].ptr; - txPtr.setTo(obtainReg(), tmu.bits); - CONTEXT_LOAD(txPtr.reg, state.texture[i].iterators.ydsdy); - ADD(AL, 0, Rx, Rx, reg_imm(txPtr.reg, ASR, 16)); // x += (s>>16) - CONTEXT_LOAD(txPtr.reg, state.texture[i].iterators.ydtdy); - ADD(AL, 0, Ry, Ry, reg_imm(txPtr.reg, ASR, 16)); // y += (t>>16) - // merge base & offset - CONTEXT_LOAD(txPtr.reg, generated_vars.texture[i].stride); - SMLABB(AL, Rx, Ry, txPtr.reg, Rx); // x+y*stride - CONTEXT_LOAD(txPtr.reg, generated_vars.texture[i].data); - base_offset(txPtr, txPtr, Rx); - } else { - Scratch scratches(registerFile()); - reg_t& s = coords[i].s; - reg_t& t = coords[i].t; - // s = (x * dsdx)>>16 + ydsdy - // s = (x * dsdx)>>16 + (y*dsdy)>>16 + s0 - // t = (x * dtdx)>>16 + ydtdy - // t = (x * dtdx)>>16 + (y*dtdy)>>16 + t0 - s.setTo(obtainReg()); - t.setTo(obtainReg()); - const int need_w = GGL_READ_NEEDS(W, needs.n); - if (need_w) { - CONTEXT_LOAD(s.reg, state.texture[i].iterators.ydsdy); - CONTEXT_LOAD(t.reg, state.texture[i].iterators.ydtdy); - } else { - int ydsdy = scratches.obtain(); - int ydtdy = scratches.obtain(); - CONTEXT_LOAD(s.reg, generated_vars.texture[i].dsdx); - CONTEXT_LOAD(ydsdy, state.texture[i].iterators.ydsdy); - CONTEXT_LOAD(t.reg, generated_vars.texture[i].dtdx); - CONTEXT_LOAD(ydtdy, state.texture[i].iterators.ydtdy); - MLA(AL, 0, s.reg, Rx, s.reg, ydsdy); - MLA(AL, 0, t.reg, Rx, t.reg, ydtdy); - } - - if ((mOptLevel&1)==0) { - CONTEXT_STORE(s.reg, generated_vars.texture[i].spill[0]); - CONTEXT_STORE(t.reg, generated_vars.texture[i].spill[1]); - recycleReg(s.reg); - recycleReg(t.reg); - } - } - - // direct texture? - if (!multiTexture && !mBlending && !mDithering && !mFog && - cb_format_idx == tmu.format_idx && !tmu.linear && - mTextureMachine.replaced == tmu.mask) - { - mTextureMachine.directTexture = i + 1; - } - } -} - -void GGLAssembler::build_textures( fragment_parts_t& parts, - Scratch& regs) -{ - context_t const* c = mBuilderContext.c; - const needs_t& needs = mBuilderContext.needs; - int Rctx = mBuilderContext.Rctx; - - // We don't have a way to spill registers automatically - // spill depth and AA regs, when we know we may have to. - // build the spill list... - uint32_t spill_list = 0; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) { - const texture_unit_t& tmu = mTextureMachine.tmu[i]; - if (tmu.format_idx == 0) - continue; - if (tmu.linear) { - // we may run out of register if we have linear filtering - // at 1 or 4 bytes / pixel on any texture unit. - if (tmu.format.size == 1) { - // if depth and AA enabled, we'll run out of 1 register - if (parts.z.reg > 0 && parts.covPtr.reg > 0) - spill_list |= 1<<parts.covPtr.reg; - } - if (tmu.format.size == 4) { - // if depth or AA enabled, we'll run out of 1 or 2 registers - if (parts.z.reg > 0) - spill_list |= 1<<parts.z.reg; - if (parts.covPtr.reg > 0) - spill_list |= 1<<parts.covPtr.reg; - } - } - } - - Spill spill(registerFile(), *this, spill_list); - - const bool multiTexture = mTextureMachine.activeUnits > 1; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) { - const texture_unit_t& tmu = mTextureMachine.tmu[i]; - if (tmu.format_idx == 0) - continue; - - pointer_t& txPtr = parts.coords[i].ptr; - pixel_t& texel = parts.texel[i]; - - // repeat... - if ((tmu.swrap == GGL_NEEDS_WRAP_11) && - (tmu.twrap == GGL_NEEDS_WRAP_11)) - { // 1:1 textures - comment("fetch texel"); - texel.setTo(regs.obtain(), &tmu.format); - load(txPtr, texel, WRITE_BACK); - } else { - Scratch scratches(registerFile()); - reg_t& s = parts.coords[i].s; - reg_t& t = parts.coords[i].t; - if ((mOptLevel&1)==0) { - comment("reload s/t (multitexture or linear filtering)"); - s.reg = scratches.obtain(); - t.reg = scratches.obtain(); - CONTEXT_LOAD(s.reg, generated_vars.texture[i].spill[0]); - CONTEXT_LOAD(t.reg, generated_vars.texture[i].spill[1]); - } - - comment("compute repeat/clamp"); - int u = scratches.obtain(); - int v = scratches.obtain(); - int width = scratches.obtain(); - int height = scratches.obtain(); - int U = 0; - int V = 0; - - CONTEXT_LOAD(width, generated_vars.texture[i].width); - CONTEXT_LOAD(height, generated_vars.texture[i].height); - - int FRAC_BITS = 0; - if (tmu.linear) { - // linear interpolation - if (tmu.format.size == 1) { - // for 8-bits textures, we can afford - // 7 bits of fractional precision at no - // additional cost (we can't do 8 bits - // because filter8 uses signed 16 bits muls) - FRAC_BITS = 7; - } else if (tmu.format.size == 2) { - // filter16() is internally limited to 4 bits, so: - // FRAC_BITS=2 generates less instructions, - // FRAC_BITS=3,4,5 creates unpleasant artifacts, - // FRAC_BITS=6+ looks good - FRAC_BITS = 6; - } else if (tmu.format.size == 4) { - // filter32() is internally limited to 8 bits, so: - // FRAC_BITS=4 looks good - // FRAC_BITS=5+ looks better, but generates 3 extra ipp - FRAC_BITS = 6; - } else { - // for all other cases we use 4 bits. - FRAC_BITS = 4; - } - } - wrapping(u, s.reg, width, tmu.swrap, FRAC_BITS); - wrapping(v, t.reg, height, tmu.twrap, FRAC_BITS); - - if (tmu.linear) { - comment("compute linear filtering offsets"); - // pixel size scale - const int shift = 31 - gglClz(tmu.format.size); - U = scratches.obtain(); - V = scratches.obtain(); - - // sample the texel center - SUB(AL, 0, u, u, imm(1<<(FRAC_BITS-1))); - SUB(AL, 0, v, v, imm(1<<(FRAC_BITS-1))); - - // get the fractionnal part of U,V - AND(AL, 0, U, u, imm((1<<FRAC_BITS)-1)); - AND(AL, 0, V, v, imm((1<<FRAC_BITS)-1)); - - // compute width-1 and height-1 - SUB(AL, 0, width, width, imm(1)); - SUB(AL, 0, height, height, imm(1)); - - // get the integer part of U,V and clamp/wrap - // and compute offset to the next texel - if (tmu.swrap == GGL_NEEDS_WRAP_REPEAT) { - // u has already been REPEATed - MOV(AL, 1, u, reg_imm(u, ASR, FRAC_BITS)); - MOV(MI, 0, u, width); - CMP(AL, u, width); - MOV(LT, 0, width, imm(1 << shift)); - if (shift) - MOV(GE, 0, width, reg_imm(width, LSL, shift)); - RSB(GE, 0, width, width, imm(0)); - } else { - // u has not been CLAMPed yet - // algorithm: - // if ((u>>4) >= width) - // u = width<<4 - // width = 0 - // else - // width = 1<<shift - // u = u>>4; // get integer part - // if (u<0) - // u = 0 - // width = 0 - // generated_vars.rt = width - - CMP(AL, width, reg_imm(u, ASR, FRAC_BITS)); - MOV(LE, 0, u, reg_imm(width, LSL, FRAC_BITS)); - MOV(LE, 0, width, imm(0)); - MOV(GT, 0, width, imm(1 << shift)); - MOV(AL, 1, u, reg_imm(u, ASR, FRAC_BITS)); - MOV(MI, 0, u, imm(0)); - MOV(MI, 0, width, imm(0)); - } - CONTEXT_STORE(width, generated_vars.rt); - - const int stride = width; - CONTEXT_LOAD(stride, generated_vars.texture[i].stride); - if (tmu.twrap == GGL_NEEDS_WRAP_REPEAT) { - // v has already been REPEATed - MOV(AL, 1, v, reg_imm(v, ASR, FRAC_BITS)); - MOV(MI, 0, v, height); - CMP(AL, v, height); - MOV(LT, 0, height, imm(1 << shift)); - if (shift) - MOV(GE, 0, height, reg_imm(height, LSL, shift)); - RSB(GE, 0, height, height, imm(0)); - MUL(AL, 0, height, stride, height); - } else { - // u has not been CLAMPed yet - CMP(AL, height, reg_imm(v, ASR, FRAC_BITS)); - MOV(LE, 0, v, reg_imm(height, LSL, FRAC_BITS)); - MOV(LE, 0, height, imm(0)); - if (shift) { - MOV(GT, 0, height, reg_imm(stride, LSL, shift)); - } else { - MOV(GT, 0, height, stride); - } - MOV(AL, 1, v, reg_imm(v, ASR, FRAC_BITS)); - MOV(MI, 0, v, imm(0)); - MOV(MI, 0, height, imm(0)); - } - CONTEXT_STORE(height, generated_vars.lb); - } - - scratches.recycle(width); - scratches.recycle(height); - - // iterate texture coordinates... - comment("iterate s,t"); - int dsdx = scratches.obtain(); - int dtdx = scratches.obtain(); - CONTEXT_LOAD(dsdx, generated_vars.texture[i].dsdx); - CONTEXT_LOAD(dtdx, generated_vars.texture[i].dtdx); - ADD(AL, 0, s.reg, s.reg, dsdx); - ADD(AL, 0, t.reg, t.reg, dtdx); - if ((mOptLevel&1)==0) { - CONTEXT_STORE(s.reg, generated_vars.texture[i].spill[0]); - CONTEXT_STORE(t.reg, generated_vars.texture[i].spill[1]); - scratches.recycle(s.reg); - scratches.recycle(t.reg); - } - scratches.recycle(dsdx); - scratches.recycle(dtdx); - - // merge base & offset... - comment("merge base & offset"); - texel.setTo(regs.obtain(), &tmu.format); - txPtr.setTo(texel.reg, tmu.bits); - int stride = scratches.obtain(); - CONTEXT_LOAD(stride, generated_vars.texture[i].stride); - CONTEXT_LOAD(txPtr.reg, generated_vars.texture[i].data); - SMLABB(AL, u, v, stride, u); // u+v*stride - base_offset(txPtr, txPtr, u); - - // load texel - if (!tmu.linear) { - comment("fetch texel"); - load(txPtr, texel, 0); - } else { - // recycle registers we don't need anymore - scratches.recycle(u); - scratches.recycle(v); - scratches.recycle(stride); - - comment("fetch texel, bilinear"); - switch (tmu.format.size) { - case 1: filter8(parts, texel, tmu, U, V, txPtr, FRAC_BITS); break; - case 2: filter16(parts, texel, tmu, U, V, txPtr, FRAC_BITS); break; - case 3: filter24(parts, texel, tmu, U, V, txPtr, FRAC_BITS); break; - case 4: filter32(parts, texel, tmu, U, V, txPtr, FRAC_BITS); break; - } - } - } - } -} - -void GGLAssembler::build_iterate_texture_coordinates( - const fragment_parts_t& parts) -{ - const bool multiTexture = mTextureMachine.activeUnits > 1; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT; i++) { - const texture_unit_t& tmu = mTextureMachine.tmu[i]; - if (tmu.format_idx == 0) - continue; - - if ((tmu.swrap == GGL_NEEDS_WRAP_11) && - (tmu.twrap == GGL_NEEDS_WRAP_11)) - { // 1:1 textures - const pointer_t& txPtr = parts.coords[i].ptr; - ADD(AL, 0, txPtr.reg, txPtr.reg, imm(txPtr.size>>3)); - } else { - Scratch scratches(registerFile()); - int s = parts.coords[i].s.reg; - int t = parts.coords[i].t.reg; - if ((mOptLevel&1)==0) { - s = scratches.obtain(); - t = scratches.obtain(); - CONTEXT_LOAD(s, generated_vars.texture[i].spill[0]); - CONTEXT_LOAD(t, generated_vars.texture[i].spill[1]); - } - int dsdx = scratches.obtain(); - int dtdx = scratches.obtain(); - CONTEXT_LOAD(dsdx, generated_vars.texture[i].dsdx); - CONTEXT_LOAD(dtdx, generated_vars.texture[i].dtdx); - ADD(AL, 0, s, s, dsdx); - ADD(AL, 0, t, t, dtdx); - if ((mOptLevel&1)==0) { - CONTEXT_STORE(s, generated_vars.texture[i].spill[0]); - CONTEXT_STORE(t, generated_vars.texture[i].spill[1]); - } - } - } -} - -void GGLAssembler::filter8( - const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS) -{ - if (tmu.format.components != GGL_ALPHA && - tmu.format.components != GGL_LUMINANCE) - { - // this is a packed format, and we don't support - // linear filtering (it's probably RGB 332) - // Should not happen with OpenGL|ES - LDRB(AL, texel.reg, txPtr.reg); - return; - } - - // ------------------------ - // about ~22 cycles / pixel - Scratch scratches(registerFile()); - - int pixel= scratches.obtain(); - int d = scratches.obtain(); - int u = scratches.obtain(); - int k = scratches.obtain(); - int rt = scratches.obtain(); - int lb = scratches.obtain(); - - // RB -> U * V - - CONTEXT_LOAD(rt, generated_vars.rt); - CONTEXT_LOAD(lb, generated_vars.lb); - - int offset = pixel; - ADD(AL, 0, offset, lb, rt); - LDRB(AL, pixel, txPtr.reg, reg_scale_pre(offset)); - SMULBB(AL, u, U, V); - SMULBB(AL, d, pixel, u); - RSB(AL, 0, k, u, imm(1<<(FRAC_BITS*2))); - - // LB -> (1-U) * V - RSB(AL, 0, U, U, imm(1<<FRAC_BITS)); - LDRB(AL, pixel, txPtr.reg, reg_scale_pre(lb)); - SMULBB(AL, u, U, V); - SMLABB(AL, d, pixel, u, d); - SUB(AL, 0, k, k, u); - - // LT -> (1-U)*(1-V) - RSB(AL, 0, V, V, imm(1<<FRAC_BITS)); - LDRB(AL, pixel, txPtr.reg); - SMULBB(AL, u, U, V); - SMLABB(AL, d, pixel, u, d); - - // RT -> U*(1-V) - LDRB(AL, pixel, txPtr.reg, reg_scale_pre(rt)); - SUB(AL, 0, u, k, u); - SMLABB(AL, texel.reg, pixel, u, d); - - for (int i=0 ; i<4 ; i++) { - if (!texel.format.c[i].h) continue; - texel.format.c[i].h = FRAC_BITS*2+8; - texel.format.c[i].l = FRAC_BITS*2; // keeping 8 bits in enough - } - texel.format.size = 4; - texel.format.bitsPerPixel = 32; - texel.flags |= CLEAR_LO; -} - -void GGLAssembler::filter16( - const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS) -{ - // compute the mask - // XXX: it would be nice if the mask below could be computed - // automatically. - uint32_t mask = 0; - int shift = 0; - int prec = 0; - switch (tmu.format_idx) { - case GGL_PIXEL_FORMAT_RGB_565: - // source: 00000ggg.ggg00000 | rrrrr000.000bbbbb - // result: gggggggg.gggrrrrr | rrrrr0bb.bbbbbbbb - mask = 0x07E0F81F; - shift = 16; - prec = 5; - break; - case GGL_PIXEL_FORMAT_RGBA_4444: - // 0000,1111,0000,1111 | 0000,1111,0000,1111 - mask = 0x0F0F0F0F; - shift = 12; - prec = 4; - break; - case GGL_PIXEL_FORMAT_LA_88: - // 0000,0000,1111,1111 | 0000,0000,1111,1111 - // AALL -> 00AA | 00LL - mask = 0x00FF00FF; - shift = 8; - prec = 8; - break; - default: - // unsupported format, do something sensical... - LOGE("Unsupported 16-bits texture format (%d)", tmu.format_idx); - LDRH(AL, texel.reg, txPtr.reg); - return; - } - - const int adjust = FRAC_BITS*2 - prec; - const int round = 0; - - // update the texel format - texel.format.size = 4; - texel.format.bitsPerPixel = 32; - texel.flags |= CLEAR_HI|CLEAR_LO; - for (int i=0 ; i<4 ; i++) { - if (!texel.format.c[i].h) continue; - const uint32_t offset = (mask & tmu.format.mask(i)) ? 0 : shift; - texel.format.c[i].h = tmu.format.c[i].h + offset + prec; - texel.format.c[i].l = texel.format.c[i].h - (tmu.format.bits(i) + prec); - } - - // ------------------------ - // about ~40 cycles / pixel - Scratch scratches(registerFile()); - - int pixel= scratches.obtain(); - int d = scratches.obtain(); - int u = scratches.obtain(); - int k = scratches.obtain(); - - // RB -> U * V - int offset = pixel; - CONTEXT_LOAD(offset, generated_vars.rt); - CONTEXT_LOAD(u, generated_vars.lb); - ADD(AL, 0, offset, offset, u); - - LDRH(AL, pixel, txPtr.reg, reg_pre(offset)); - SMULBB(AL, u, U, V); - ORR(AL, 0, pixel, pixel, reg_imm(pixel, LSL, shift)); - build_and_immediate(pixel, pixel, mask, 32); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MUL(AL, 0, d, pixel, u); - RSB(AL, 0, k, u, imm(1<<prec)); - - // LB -> (1-U) * V - CONTEXT_LOAD(offset, generated_vars.lb); - RSB(AL, 0, U, U, imm(1<<FRAC_BITS)); - LDRH(AL, pixel, txPtr.reg, reg_pre(offset)); - SMULBB(AL, u, U, V); - ORR(AL, 0, pixel, pixel, reg_imm(pixel, LSL, shift)); - build_and_immediate(pixel, pixel, mask, 32); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MLA(AL, 0, d, pixel, u, d); - SUB(AL, 0, k, k, u); - - // LT -> (1-U)*(1-V) - RSB(AL, 0, V, V, imm(1<<FRAC_BITS)); - LDRH(AL, pixel, txPtr.reg); - SMULBB(AL, u, U, V); - ORR(AL, 0, pixel, pixel, reg_imm(pixel, LSL, shift)); - build_and_immediate(pixel, pixel, mask, 32); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MLA(AL, 0, d, pixel, u, d); - - // RT -> U*(1-V) - CONTEXT_LOAD(offset, generated_vars.rt); - LDRH(AL, pixel, txPtr.reg, reg_pre(offset)); - SUB(AL, 0, u, k, u); - ORR(AL, 0, pixel, pixel, reg_imm(pixel, LSL, shift)); - build_and_immediate(pixel, pixel, mask, 32); - MLA(AL, 0, texel.reg, pixel, u, d); -} - -void GGLAssembler::filter24( - const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS) -{ - // not supported yet (currently disabled) - load(txPtr, texel, 0); -} - -void GGLAssembler::filter32( - const fragment_parts_t& parts, - pixel_t& texel, const texture_unit_t& tmu, - int U, int V, pointer_t& txPtr, - int FRAC_BITS) -{ - const int adjust = FRAC_BITS*2 - 8; - const int round = 0; - - // ------------------------ - // about ~38 cycles / pixel - Scratch scratches(registerFile()); - - int pixel= scratches.obtain(); - int dh = scratches.obtain(); - int u = scratches.obtain(); - int k = scratches.obtain(); - - int temp = scratches.obtain(); - int dl = scratches.obtain(); - int mask = scratches.obtain(); - - MOV(AL, 0, mask, imm(0xFF)); - ORR(AL, 0, mask, mask, imm(0xFF0000)); - - // RB -> U * V - int offset = pixel; - CONTEXT_LOAD(offset, generated_vars.rt); - CONTEXT_LOAD(u, generated_vars.lb); - ADD(AL, 0, offset, offset, u); - - LDR(AL, pixel, txPtr.reg, reg_scale_pre(offset)); - SMULBB(AL, u, U, V); - AND(AL, 0, temp, mask, pixel); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MUL(AL, 0, dh, temp, u); - AND(AL, 0, temp, mask, reg_imm(pixel, LSR, 8)); - MUL(AL, 0, dl, temp, u); - RSB(AL, 0, k, u, imm(0x100)); - - // LB -> (1-U) * V - CONTEXT_LOAD(offset, generated_vars.lb); - RSB(AL, 0, U, U, imm(1<<FRAC_BITS)); - LDR(AL, pixel, txPtr.reg, reg_scale_pre(offset)); - SMULBB(AL, u, U, V); - AND(AL, 0, temp, mask, pixel); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MLA(AL, 0, dh, temp, u, dh); - AND(AL, 0, temp, mask, reg_imm(pixel, LSR, 8)); - MLA(AL, 0, dl, temp, u, dl); - SUB(AL, 0, k, k, u); - - // LT -> (1-U)*(1-V) - RSB(AL, 0, V, V, imm(1<<FRAC_BITS)); - LDR(AL, pixel, txPtr.reg); - SMULBB(AL, u, U, V); - AND(AL, 0, temp, mask, pixel); - if (adjust) { - if (round) - ADD(AL, 0, u, u, imm(1<<(adjust-1))); - MOV(AL, 0, u, reg_imm(u, LSR, adjust)); - } - MLA(AL, 0, dh, temp, u, dh); - AND(AL, 0, temp, mask, reg_imm(pixel, LSR, 8)); - MLA(AL, 0, dl, temp, u, dl); - - // RT -> U*(1-V) - CONTEXT_LOAD(offset, generated_vars.rt); - LDR(AL, pixel, txPtr.reg, reg_scale_pre(offset)); - SUB(AL, 0, u, k, u); - AND(AL, 0, temp, mask, pixel); - MLA(AL, 0, dh, temp, u, dh); - AND(AL, 0, temp, mask, reg_imm(pixel, LSR, 8)); - MLA(AL, 0, dl, temp, u, dl); - - AND(AL, 0, dh, mask, reg_imm(dh, LSR, 8)); - AND(AL, 0, dl, dl, reg_imm(mask, LSL, 8)); - ORR(AL, 0, texel.reg, dh, dl); -} - -void GGLAssembler::build_texture_environment( - component_t& fragment, - const fragment_parts_t& parts, - int component, - Scratch& regs) -{ - const uint32_t component_mask = 1<<component; - const bool multiTexture = mTextureMachine.activeUnits > 1; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; i++) { - texture_unit_t& tmu = mTextureMachine.tmu[i]; - - if (tmu.mask & component_mask) { - // replace or modulate with this texture - if ((tmu.replaced & component_mask) == 0) { - // not replaced by a later tmu... - - Scratch scratches(registerFile()); - pixel_t texel(parts.texel[i]); - if (multiTexture && - tmu.swrap == GGL_NEEDS_WRAP_11 && - tmu.twrap == GGL_NEEDS_WRAP_11) - { - texel.reg = scratches.obtain(); - texel.flags |= CORRUPTIBLE; - comment("fetch texel (multitexture 1:1)"); - load(parts.coords[i].ptr, texel, WRITE_BACK); - } - - component_t incoming(fragment); - modify(fragment, regs); - - switch (tmu.env) { - case GGL_REPLACE: - extract(fragment, texel, component); - break; - case GGL_MODULATE: - modulate(fragment, incoming, texel, component); - break; - case GGL_DECAL: - decal(fragment, incoming, texel, component); - break; - case GGL_BLEND: - blend(fragment, incoming, texel, component, i); - break; - case GGL_ADD: - add(fragment, incoming, texel, component); - break; - } - } - } - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::wrapping( - int d, - int coord, int size, - int tx_wrap, int tx_linear) -{ - // notes: - // if tx_linear is set, we need 4 extra bits of precision on the result - // SMULL/UMULL is 3 cycles - Scratch scratches(registerFile()); - int c = coord; - if (tx_wrap == GGL_NEEDS_WRAP_REPEAT) { - // UMULL takes 4 cycles (interlocked), and we can get away with - // 2 cycles using SMULWB, but we're loosing 16 bits of precision - // out of 32 (this is not a problem because the iterator keeps - // its full precision) - // UMULL(AL, 0, size, d, c, size); - // note: we can't use SMULTB because it's signed. - MOV(AL, 0, d, reg_imm(c, LSR, 16-tx_linear)); - SMULWB(AL, d, d, size); - } else if (tx_wrap == GGL_NEEDS_WRAP_CLAMP_TO_EDGE) { - if (tx_linear) { - // 1 cycle - MOV(AL, 0, d, reg_imm(coord, ASR, 16-tx_linear)); - } else { - // 4 cycles (common case) - MOV(AL, 0, d, reg_imm(coord, ASR, 16)); - BIC(AL, 0, d, d, reg_imm(d, ASR, 31)); - CMP(AL, d, size); - SUB(GE, 0, d, size, imm(1)); - } - } -} - -// --------------------------------------------------------------------------- - -void GGLAssembler::modulate( - component_t& dest, - const component_t& incoming, - const pixel_t& incomingTexel, int component) -{ - Scratch locals(registerFile()); - integer_t texel(locals.obtain(), 32, CORRUPTIBLE); - extract(texel, incomingTexel, component); - - const int Nt = texel.size(); - // Nt should always be less than 10 bits because it comes - // from the TMU. - - int Ni = incoming.size(); - // Ni could be big because it comes from previous MODULATEs - - if (Nt == 1) { - // texel acts as a bit-mask - // dest = incoming & ((texel << incoming.h)-texel) - RSB(AL, 0, dest.reg, texel.reg, reg_imm(texel.reg, LSL, incoming.h)); - AND(AL, 0, dest.reg, dest.reg, incoming.reg); - dest.l = incoming.l; - dest.h = incoming.h; - dest.flags |= (incoming.flags & CLEAR_LO); - } else if (Ni == 1) { - MOV(AL, 0, dest.reg, reg_imm(incoming.reg, LSL, 31-incoming.h)); - AND(AL, 0, dest.reg, texel.reg, reg_imm(dest.reg, ASR, 31)); - dest.l = 0; - dest.h = Nt; - } else { - int inReg = incoming.reg; - int shift = incoming.l; - if ((Nt + Ni) > 32) { - // we will overflow, reduce the precision of Ni to 8 bits - // (Note Nt cannot be more than 10 bits which happens with - // 565 textures and GGL_LINEAR) - shift += Ni-8; - Ni = 8; - } - - // modulate by the component with the lowest precision - if (Nt >= Ni) { - if (shift) { - // XXX: we should be able to avoid this shift - // when shift==16 && Nt<16 && Ni<16, in which - // we could use SMULBT below. - MOV(AL, 0, dest.reg, reg_imm(inReg, LSR, shift)); - inReg = dest.reg; - shift = 0; - } - // operation: (Cf*Ct)/((1<<Ni)-1) - // approximated with: Cf*(Ct + Ct>>(Ni-1))>>Ni - // this operation doesn't change texel's size - ADD(AL, 0, dest.reg, inReg, reg_imm(inReg, LSR, Ni-1)); - if (Nt<16 && Ni<16) SMULBB(AL, dest.reg, texel.reg, dest.reg); - else MUL(AL, 0, dest.reg, texel.reg, dest.reg); - dest.l = Ni; - dest.h = Nt + Ni; - } else { - if (shift && (shift != 16)) { - // if shift==16, we can use 16-bits mul instructions later - MOV(AL, 0, dest.reg, reg_imm(inReg, LSR, shift)); - inReg = dest.reg; - shift = 0; - } - // operation: (Cf*Ct)/((1<<Nt)-1) - // approximated with: Ct*(Cf + Cf>>(Nt-1))>>Nt - // this operation doesn't change incoming's size - Scratch scratches(registerFile()); - int t = (texel.flags & CORRUPTIBLE) ? texel.reg : dest.reg; - if (t == inReg) - t = scratches.obtain(); - ADD(AL, 0, t, texel.reg, reg_imm(texel.reg, LSR, Nt-1)); - if (Nt<16 && Ni<16) { - if (shift==16) SMULBT(AL, dest.reg, t, inReg); - else SMULBB(AL, dest.reg, t, inReg); - } else MUL(AL, 0, dest.reg, t, inReg); - dest.l = Nt; - dest.h = Nt + Ni; - } - - // low bits are not valid - dest.flags |= CLEAR_LO; - - // no need to keep more than 8 bits/component - if (dest.size() > 8) - dest.l = dest.h-8; - } -} - -void GGLAssembler::decal( - component_t& dest, - const component_t& incoming, - const pixel_t& incomingTexel, int component) -{ - // RGBA: - // Cv = Cf*(1 - At) + Ct*At = Cf + (Ct - Cf)*At - // Av = Af - Scratch locals(registerFile()); - integer_t texel(locals.obtain(), 32, CORRUPTIBLE); - integer_t factor(locals.obtain(), 32, CORRUPTIBLE); - extract(texel, incomingTexel, component); - extract(factor, incomingTexel, GGLFormat::ALPHA); - - // no need to keep more than 8-bits for decal - int Ni = incoming.size(); - int shift = incoming.l; - if (Ni > 8) { - shift += Ni-8; - Ni = 8; - } - integer_t incomingNorm(incoming.reg, Ni, incoming.flags); - if (shift) { - MOV(AL, 0, dest.reg, reg_imm(incomingNorm.reg, LSR, shift)); - incomingNorm.reg = dest.reg; - incomingNorm.flags |= CORRUPTIBLE; - } - ADD(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, LSR, factor.s-1)); - build_blendOneMinusFF(dest, factor, incomingNorm, texel); -} - -void GGLAssembler::blend( - component_t& dest, - const component_t& incoming, - const pixel_t& incomingTexel, int component, int tmu) -{ - // RGBA: - // Cv = (1 - Ct)*Cf + Ct*Cc = Cf + (Cc - Cf)*Ct - // Av = At*Af - - if (component == GGLFormat::ALPHA) { - modulate(dest, incoming, incomingTexel, component); - return; - } - - Scratch locals(registerFile()); - integer_t color(locals.obtain(), 8, CORRUPTIBLE); - integer_t factor(locals.obtain(), 32, CORRUPTIBLE); - LDRB(AL, color.reg, mBuilderContext.Rctx, - immed12_pre(GGL_OFFSETOF(state.texture[tmu].env_color[component]))); - extract(factor, incomingTexel, component); - - // no need to keep more than 8-bits for blend - int Ni = incoming.size(); - int shift = incoming.l; - if (Ni > 8) { - shift += Ni-8; - Ni = 8; - } - integer_t incomingNorm(incoming.reg, Ni, incoming.flags); - if (shift) { - MOV(AL, 0, dest.reg, reg_imm(incomingNorm.reg, LSR, shift)); - incomingNorm.reg = dest.reg; - incomingNorm.flags |= CORRUPTIBLE; - } - ADD(AL, 0, factor.reg, factor.reg, reg_imm(factor.reg, LSR, factor.s-1)); - build_blendOneMinusFF(dest, factor, incomingNorm, color); -} - -void GGLAssembler::add( - component_t& dest, - const component_t& incoming, - const pixel_t& incomingTexel, int component) -{ - // RGBA: - // Cv = Cf + Ct; - Scratch locals(registerFile()); - - component_t incomingTemp(incoming); - - // use "dest" as a temporary for extracting the texel, unless "dest" - // overlaps "incoming". - integer_t texel(dest.reg, 32, CORRUPTIBLE); - if (dest.reg == incomingTemp.reg) - texel.reg = locals.obtain(); - extract(texel, incomingTexel, component); - - if (texel.s < incomingTemp.size()) { - expand(texel, texel, incomingTemp.size()); - } else if (texel.s > incomingTemp.size()) { - if (incomingTemp.flags & CORRUPTIBLE) { - expand(incomingTemp, incomingTemp, texel.s); - } else { - incomingTemp.reg = locals.obtain(); - expand(incomingTemp, incoming, texel.s); - } - } - - if (incomingTemp.l) { - ADD(AL, 0, dest.reg, texel.reg, - reg_imm(incomingTemp.reg, LSR, incomingTemp.l)); - } else { - ADD(AL, 0, dest.reg, texel.reg, incomingTemp.reg); - } - dest.l = 0; - dest.h = texel.size(); - component_sat(dest); -} - -// ---------------------------------------------------------------------------- - -}; // namespace android - diff --git a/libpixelflinger/fixed.cpp b/libpixelflinger/fixed.cpp deleted file mode 100644 index 5b920628bad1e6d5a9c6a871e6e81df906d0b8a6..0000000000000000000000000000000000000000 --- a/libpixelflinger/fixed.cpp +++ /dev/null @@ -1,339 +0,0 @@ -/* libs/pixelflinger/fixed.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> - -#include <private/pixelflinger/ggl_context.h> -#include <private/pixelflinger/ggl_fixed.h> - - -// ------------------------------------------------------------------------ - -int32_t gglRecipQNormalized(int32_t x, int* exponent) -{ - const int32_t s = x>>31; - uint32_t a = s ? -x : x; - - // the result will overflow, so just set it to the biggest/inf value - if (ggl_unlikely(a <= 2LU)) { - *exponent = 0; - return s ? FIXED_MIN : FIXED_MAX; - } - - // Newton-Raphson iteration: - // x = r*(2 - a*r) - - const int32_t lz = gglClz(a); - a <<= lz; // 0.32 - uint32_t r = a; - // note: if a == 0x80000000, this means x was a power-of-2, in this - // case we don't need to compute anything. We get the reciprocal for - // (almost) free. - if (a != 0x80000000) { - r = (0x2E800 << (30-16)) - (r>>(2-1)); // 2.30, r = 2.90625 - 2*a - // 0.32 + 2.30 = 2.62 -> 2.30 - // 2.30 + 2.30 = 4.60 -> 2.30 - r = (((2LU<<30) - uint32_t((uint64_t(a)*r) >> 32)) * uint64_t(r)) >> 30; - r = (((2LU<<30) - uint32_t((uint64_t(a)*r) >> 32)) * uint64_t(r)) >> 30; - } - - // shift right 1-bit to make room for the sign bit - *exponent = 30-lz-1; - r >>= 1; - return s ? -r : r; -} - -int32_t gglRecipQ(GGLfixed x, int q) -{ - int shift; - x = gglRecipQNormalized(x, &shift); - shift += 16-q; - x += 1L << (shift-1); // rounding - x >>= shift; - return x; -} - -// ------------------------------------------------------------------------ - -GGLfixed gglFastDivx(GGLfixed n, GGLfixed d) -{ - if ((d>>24) && ((d>>24)+1)) { - n >>= 8; - d >>= 8; - } - return gglMulx(n, gglRecip(d)); -} - -// ------------------------------------------------------------------------ - -static const GGLfixed ggl_sqrt_reciproc_approx_tab[8] = { - // 1/sqrt(x) with x = 1-N/16, N=[8...1] - 0x16A09, 0x15555, 0x143D1, 0x134BF, 0x1279A, 0x11C01, 0x111AC, 0x10865 -}; - -GGLfixed gglSqrtRecipx(GGLfixed x) -{ - if (x == 0) return FIXED_MAX; - if (x == FIXED_ONE) return x; - const GGLfixed a = x; - const int32_t lz = gglClz(x); - x = ggl_sqrt_reciproc_approx_tab[(a>>(28-lz))&0x7]; - const int32_t exp = lz - 16; - if (exp <= 0) x >>= -exp>>1; - else x <<= (exp>>1) + (exp & 1); - if (exp & 1) { - x = gglMulx(x, ggl_sqrt_reciproc_approx_tab[0])>>1; - } - // 2 Newton-Raphson iterations: x = x/2*(3-(a*x)*x) - x = gglMulx((x>>1),(0x30000 - gglMulx(gglMulx(a,x),x))); - x = gglMulx((x>>1),(0x30000 - gglMulx(gglMulx(a,x),x))); - return x; -} - -GGLfixed gglSqrtx(GGLfixed a) -{ - // Compute a full precision square-root (24 bits accuracy) - GGLfixed r = 0; - GGLfixed bit = 0x800000; - int32_t bshift = 15; - do { - GGLfixed temp = bit + (r<<1); - if (bshift >= 8) temp <<= (bshift-8); - else temp >>= (8-bshift); - if (a >= temp) { - r += bit; - a -= temp; - } - bshift--; - } while (bit>>=1); - return r; -} - -// ------------------------------------------------------------------------ - -static const GGLfixed ggl_log_approx_tab[] = { - // -ln(x)/ln(2) with x = N/16, N=[8...16] - 0xFFFF, 0xd47f, 0xad96, 0x8a62, 0x6a3f, 0x4caf, 0x3151, 0x17d6, 0x0000 -}; - -static const GGLfixed ggl_alog_approx_tab[] = { // domain [0 - 1.0] - 0xffff, 0xeac0, 0xd744, 0xc567, 0xb504, 0xa5fe, 0x9837, 0x8b95, 0x8000 -}; - -GGLfixed gglPowx(GGLfixed x, GGLfixed y) -{ - // prerequisite: 0 <= x <= 1, and y >=0 - - // pow(x,y) = 2^(y*log2(x)) - // = 2^(y*log2(x*(2^exp)*(2^-exp)))) - // = 2^(y*(log2(X)-exp)) - // = 2^(log2(X)*y - y*exp) - // = 2^( - (-log2(X)*y + y*exp) ) - - int32_t exp = gglClz(x) - 16; - GGLfixed f = x << exp; - x = (f & 0x0FFF)<<4; - f = (f >> 12) & 0x7; - GGLfixed p = gglMulAddx( - ggl_log_approx_tab[f+1] - ggl_log_approx_tab[f], x, - ggl_log_approx_tab[f]); - p = gglMulAddx(p, y, y*exp); - exp = gglFixedToIntFloor(p); - if (exp < 31) { - p = gglFracx(p); - x = (p & 0x1FFF)<<3; - p >>= 13; - p = gglMulAddx( - ggl_alog_approx_tab[p+1] - ggl_alog_approx_tab[p], x, - ggl_alog_approx_tab[p]); - p >>= exp; - } else { - p = 0; - } - return p; - // ( powf((a*65536.0f), (b*65536.0f)) ) * 65536.0f; -} - -// ------------------------------------------------------------------------ - -int32_t gglDivQ(GGLfixed n, GGLfixed d, int32_t i) -{ - //int32_t r =int32_t((int64_t(n)<<i)/d); - const int32_t ds = n^d; - if (n<0) n = -n; - if (d<0) d = -d; - int nd = gglClz(d) - gglClz(n); - i += nd + 1; - if (nd > 0) d <<= nd; - else n <<= -nd; - uint32_t q = 0; - - int j = i & 7; - i >>= 3; - - // gcc deals with the code below pretty well. - // we get 3.75 cycles per bit in the main loop - // and 8 cycles per bit in the termination loop - if (ggl_likely(i)) { - n -= d; - do { - q <<= 8; - if (n>=0) q |= 128; - else n += d; - n = n*2 - d; - if (n>=0) q |= 64; - else n += d; - n = n*2 - d; - if (n>=0) q |= 32; - else n += d; - n = n*2 - d; - if (n>=0) q |= 16; - else n += d; - n = n*2 - d; - if (n>=0) q |= 8; - else n += d; - n = n*2 - d; - if (n>=0) q |= 4; - else n += d; - n = n*2 - d; - if (n>=0) q |= 2; - else n += d; - n = n*2 - d; - if (n>=0) q |= 1; - else n += d; - - if (--i == 0) - goto finish; - - n = n*2 - d; - } while(true); - do { - q <<= 1; - n = n*2 - d; - if (n>=0) q |= 1; - else n += d; - finish: ; - } while (j--); - return (ds<0) ? -q : q; - } - - n -= d; - if (n>=0) q |= 1; - else n += d; - j--; - goto finish; -} - -// ------------------------------------------------------------------------ - -// assumes that the int32_t values of a, b, and c are all positive -// use when both a and b are larger than c - -template <typename T> -static inline void swap(T& a, T& b) { - T t(a); - a = b; - b = t; -} - -static __attribute__((noinline)) -int32_t slow_muldiv(uint32_t a, uint32_t b, uint32_t c) -{ - // first we compute a*b as a 64-bit integer - // (GCC generates umull with the code below) - uint64_t ab = uint64_t(a)*b; - uint32_t hi = ab>>32; - uint32_t lo = ab; - uint32_t result; - - // now perform the division - if (hi >= c) { - overflow: - result = 0x7fffffff; // basic overflow - } else if (hi == 0) { - result = lo/c; // note: c can't be 0 - if ((result >> 31) != 0) // result must fit in 31 bits - goto overflow; - } else { - uint32_t r = hi; - int bits = 31; - result = 0; - do { - r = (r << 1) | (lo >> 31); - lo <<= 1; - result <<= 1; - if (r >= c) { - r -= c; - result |= 1; - } - } while (bits--); - } - return int32_t(result); -} - -// assumes a >= 0 and c >= b >= 0 -static inline -int32_t quick_muldiv(int32_t a, int32_t b, int32_t c) -{ - int32_t r = 0, q = 0, i; - int leading = gglClz(a); - i = 32 - leading; - a <<= leading; - do { - r <<= 1; - if (a < 0) - r += b; - a <<= 1; - q <<= 1; - if (r >= c) { - r -= c; - q++; - } - asm(""::); // gcc generates better code this way - if (r >= c) { - r -= c; - q++; - } - } - while (--i); - return q; -} - -// this function computes a*b/c with 64-bit intermediate accuracy -// overflows (e.g. division by 0) are handled and return INT_MAX - -int32_t gglMulDivi(int32_t a, int32_t b, int32_t c) -{ - int32_t result; - int32_t sign = a^b^c; - - if (a < 0) a = -a; - if (b < 0) b = -b; - if (c < 0) c = -c; - - if (a < b) { - swap(a, b); - } - - if (b <= c) result = quick_muldiv(a, b, c); - else result = slow_muldiv((uint32_t)a, (uint32_t)b, (uint32_t)c); - - if (sign < 0) - result = -result; - - return result; -} diff --git a/libpixelflinger/format.cpp b/libpixelflinger/format.cpp deleted file mode 100644 index 161e6d6ee638ec122fe3570276eafcd16054a14a..0000000000000000000000000000000000000000 --- a/libpixelflinger/format.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* libs/pixelflinger/format.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> -#include <pixelflinger/format.h> - -namespace android { - -static GGLFormat const gPixelFormatInfos[] = -{ // Alpha Red Green Blue - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - { 4, 32, {{32,24, 8, 0, 16, 8, 24,16 }}, GGL_RGBA }, // PIXEL_FORMAT_RGBA_8888 - { 4, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // PIXEL_FORMAT_RGBX_8888 - { 3, 24, {{ 0, 0, 8, 0, 16, 8, 24,16 }}, GGL_RGB }, // PIXEL_FORMAT_RGB_888 - { 2, 16, {{ 0, 0, 16,11, 11, 5, 5, 0 }}, GGL_RGB }, // PIXEL_FORMAT_RGB_565 - { 4, 32, {{32,24, 24,16, 16, 8, 8, 0 }}, GGL_RGBA }, // PIXEL_FORMAT_BGRA_8888 - { 2, 16, {{ 1, 0, 16,11, 11, 6, 6, 1 }}, GGL_RGBA }, // PIXEL_FORMAT_RGBA_5551 - { 2, 16, {{ 4, 0, 16,12, 12, 8, 8, 4 }}, GGL_RGBA }, // PIXEL_FORMAT_RGBA_4444 - { 1, 8, {{ 8, 0, 0, 0, 0, 0, 0, 0 }}, GGL_ALPHA}, // PIXEL_FORMAT_A8 - { 1, 8, {{ 0, 0, 8, 0, 8, 0, 8, 0 }}, GGL_LUMINANCE},//PIXEL_FORMAT_L8 - { 2, 16, {{16, 8, 8, 0, 8, 0, 8, 0 }}, GGL_LUMINANCE_ALPHA},// PIXEL_FORMAT_LA_88 - { 1, 8, {{ 0, 0, 8, 5, 5, 2, 2, 0 }}, GGL_RGB }, // PIXEL_FORMAT_RGB_332 - - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - - { 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_422_SP - { 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_SP },// PIXEL_FORMAT_YCbCr_420_SP - { 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_422_P - { 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_P }, // PIXEL_FORMAT_YCbCr_420_P - { 1, 16, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_422_I - { 1, 12, {{ 0, 8, 0, 8, 0, 8, 0, 0 }}, GGL_Y_CB_CR_I }, // PIXEL_FORMAT_YCbCr_420_I - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - { 0, 0, {{ 0, 0, 0, 0, 0, 0, 0, 0 }}, 0 }, // PIXEL_FORMAT_NONE - - { 2, 16, {{ 0, 0, 16, 0, 0, 0, 0, 0 }}, GGL_DEPTH_COMPONENT}, - { 1, 8, {{ 8, 0, 0, 0, 0, 0, 0, 0 }}, GGL_STENCIL_INDEX }, - { 4, 24, {{ 0, 0, 24, 0, 0, 0, 0, 0 }}, GGL_DEPTH_COMPONENT}, - { 4, 8, {{ 32,24, 0, 0, 0, 0, 0, 0 }}, GGL_STENCIL_INDEX }, -}; - -}; // namespace android - - -const GGLFormat* gglGetPixelFormatTable(size_t* numEntries) -{ - if (numEntries) { - *numEntries = sizeof(android::gPixelFormatInfos)/sizeof(GGLFormat); - } - return android::gPixelFormatInfos; -} diff --git a/libpixelflinger/picker.cpp b/libpixelflinger/picker.cpp deleted file mode 100644 index 030ef1962bdea5fa9073624b31e5bf9df7eb6f03..0000000000000000000000000000000000000000 --- a/libpixelflinger/picker.cpp +++ /dev/null @@ -1,173 +0,0 @@ -/* libs/pixelflinger/picker.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <stdio.h> - -#include "buffer.h" -#include "scanline.h" -#include "picker.h" - -namespace android { - -// ---------------------------------------------------------------------------- - -void ggl_init_picker(context_t* c) -{ -} - -void ggl_pick(context_t* c) -{ - if (ggl_likely(!c->dirty)) - return; - - // compute needs, see if they changed... - const uint32_t enables = c->state.enables; - needs_t new_needs(c->state.needs); - - if (c->dirty & GGL_CB_STATE) { - new_needs.n &= ~GGL_NEEDS_CB_FORMAT_MASK; - new_needs.n |= GGL_BUILD_NEEDS(c->state.buffers.color.format, CB_FORMAT); - if (enables & GGL_ENABLE_BLENDING) - c->dirty |= GGL_PIXEL_PIPELINE_STATE; - } - - if (c->dirty & GGL_PIXEL_PIPELINE_STATE) { - uint32_t n = GGL_BUILD_NEEDS(c->state.buffers.color.format, CB_FORMAT); - uint32_t p = 0; - if (enables & GGL_ENABLE_BLENDING) { - uint32_t src = c->state.blend.src; - uint32_t dst = c->state.blend.dst; - uint32_t src_alpha = c->state.blend.src_alpha; - uint32_t dst_alpha = c->state.blend.dst_alpha; - const GGLFormat& cbf = c->formats[ c->state.buffers.color.format ]; - if (!cbf.c[GGLFormat::ALPHA].h) { - if ((src == GGL_ONE_MINUS_DST_ALPHA) || - (src == GGL_DST_ALPHA)) { - src = GGL_ONE; - } - if ((src_alpha == GGL_ONE_MINUS_DST_ALPHA) || - (src_alpha == GGL_DST_ALPHA)) { - src_alpha = GGL_ONE; - } - if ((dst == GGL_ONE_MINUS_DST_ALPHA) || - (dst == GGL_DST_ALPHA)) { - dst = GGL_ONE; - } - if ((dst_alpha == GGL_ONE_MINUS_DST_ALPHA) || - (dst_alpha == GGL_DST_ALPHA)) { - dst_alpha = GGL_ONE; - } - } - - src = ggl_blendfactor_to_needs(src); - dst = ggl_blendfactor_to_needs(dst); - src_alpha = ggl_blendfactor_to_needs(src_alpha); - dst_alpha = ggl_blendfactor_to_needs(dst_alpha); - - n |= GGL_BUILD_NEEDS( src, BLEND_SRC ); - n |= GGL_BUILD_NEEDS( dst, BLEND_DST ); - if (c->state.blend.alpha_separate) { - n |= GGL_BUILD_NEEDS( src_alpha, BLEND_SRCA ); - n |= GGL_BUILD_NEEDS( dst_alpha, BLEND_DSTA ); - } else { - n |= GGL_BUILD_NEEDS( src, BLEND_SRCA ); - n |= GGL_BUILD_NEEDS( dst, BLEND_DSTA ); - } - } else { - n |= GGL_BUILD_NEEDS( GGL_ONE, BLEND_SRC ); - n |= GGL_BUILD_NEEDS( GGL_ZERO, BLEND_DST ); - n |= GGL_BUILD_NEEDS( GGL_ONE, BLEND_SRCA ); - n |= GGL_BUILD_NEEDS( GGL_ZERO, BLEND_DSTA ); - } - - - n |= GGL_BUILD_NEEDS(c->state.mask.color^0xF, MASK_ARGB); - n |= GGL_BUILD_NEEDS((enables & GGL_ENABLE_SMOOTH) ?1:0, SHADE); - if (enables & GGL_ENABLE_TMUS) { - n |= GGL_BUILD_NEEDS((enables & GGL_ENABLE_W) ?1:0, W); - } - p |= GGL_BUILD_NEEDS((enables & GGL_ENABLE_DITHER) ?1:0, P_DITHER); - p |= GGL_BUILD_NEEDS((enables & GGL_ENABLE_AA) ?1:0, P_AA); - p |= GGL_BUILD_NEEDS((enables & GGL_ENABLE_FOG) ?1:0, P_FOG); - - if (enables & GGL_ENABLE_LOGIC_OP) { - n |= GGL_BUILD_NEEDS(c->state.logic_op.opcode, LOGIC_OP); - } else { - n |= GGL_BUILD_NEEDS(GGL_COPY, LOGIC_OP); - } - - if (enables & GGL_ENABLE_ALPHA_TEST) { - p |= GGL_BUILD_NEEDS(c->state.alpha_test.func, P_ALPHA_TEST); - } else { - p |= GGL_BUILD_NEEDS(GGL_ALWAYS, P_ALPHA_TEST); - } - - if (enables & GGL_ENABLE_DEPTH_TEST) { - p |= GGL_BUILD_NEEDS(c->state.depth_test.func, P_DEPTH_TEST); - p |= GGL_BUILD_NEEDS(c->state.mask.depth&1, P_MASK_Z); - } else { - p |= GGL_BUILD_NEEDS(GGL_ALWAYS, P_DEPTH_TEST); - // writing to the z-buffer is always disabled if depth-test - // is disabled. - } - new_needs.n = n; - new_needs.p = p; - } - - if (c->dirty & GGL_TMU_STATE) { - int idx = 0; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - const texture_t& tx = c->state.texture[i]; - if (tx.enable) { - uint32_t t = 0; - t |= GGL_BUILD_NEEDS(tx.surface.format, T_FORMAT); - t |= GGL_BUILD_NEEDS(ggl_env_to_needs(tx.env), T_ENV); - t |= GGL_BUILD_NEEDS(0, T_POT); // XXX: not used yet - if (tx.s_coord==GGL_ONE_TO_ONE && tx.t_coord==GGL_ONE_TO_ONE) { - // we encode 1-to-1 into the wrap mode - t |= GGL_BUILD_NEEDS(GGL_NEEDS_WRAP_11, T_S_WRAP); - t |= GGL_BUILD_NEEDS(GGL_NEEDS_WRAP_11, T_T_WRAP); - } else { - t |= GGL_BUILD_NEEDS(ggl_wrap_to_needs(tx.s_wrap), T_S_WRAP); - t |= GGL_BUILD_NEEDS(ggl_wrap_to_needs(tx.t_wrap), T_T_WRAP); - } - if (tx.mag_filter == GGL_LINEAR) { - t |= GGL_BUILD_NEEDS(1, T_LINEAR); - } - if (tx.min_filter == GGL_LINEAR) { - t |= GGL_BUILD_NEEDS(1, T_LINEAR); - } - new_needs.t[idx++] = t; - } else { - new_needs.t[i] = 0; - } - } - } - - if (new_needs != c->state.needs) { - c->state.needs = new_needs; - ggl_pick_texture(c); - ggl_pick_cb(c); - ggl_pick_scanline(c); - } - c->dirty = 0; -} - -// ---------------------------------------------------------------------------- -}; // namespace android - diff --git a/libpixelflinger/picker.h b/libpixelflinger/picker.h deleted file mode 100644 index 9cdbc3c12c46170fcd187a4deab25ef15b95505a..0000000000000000000000000000000000000000 --- a/libpixelflinger/picker.h +++ /dev/null @@ -1,31 +0,0 @@ -/* libs/pixelflinger/picker.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_PICKER_H -#define ANDROID_PICKER_H - -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_picker(context_t* c); -void ggl_pick(context_t* c); - -}; // namespace android - -#endif diff --git a/libpixelflinger/pixelflinger.cpp b/libpixelflinger/pixelflinger.cpp deleted file mode 100644 index b54da0c6139a57b1f20e1e3afcde7b263893b561..0000000000000000000000000000000000000000 --- a/libpixelflinger/pixelflinger.cpp +++ /dev/null @@ -1,843 +0,0 @@ -/* libs/pixelflinger/pixelflinger.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include <sys/time.h> - -#include <pixelflinger/pixelflinger.h> -#include <private/pixelflinger/ggl_context.h> - -#include "buffer.h" -#include "clear.h" -#include "picker.h" -#include "raster.h" -#include "scanline.h" -#include "trap.h" - -#include "codeflinger/GGLAssembler.h" -#include "codeflinger/CodeCache.h" - -#include <stdio.h> - - -namespace android { - -// ---------------------------------------------------------------------------- - -// 8x8 Bayer dither matrix -static const uint8_t gDitherMatrix[GGL_DITHER_SIZE] = { - 0, 32, 8, 40, 2, 34, 10, 42, - 48, 16, 56, 24, 50, 18, 58, 26, - 12, 44, 4, 36, 14, 46, 6, 38, - 60, 28, 52, 20, 62, 30, 54, 22, - 3, 35, 11, 43, 1, 33, 9, 41, - 51, 19, 59, 27, 49, 17, 57, 25, - 15, 47, 7, 39, 13, 45, 5, 37, - 63, 31, 55, 23, 61, 29, 53, 21 -}; - -static void ggl_init_procs(context_t* c); -static void ggl_set_scissor(context_t* c); - -static void ggl_enable_blending(context_t* c, int enable); -static void ggl_enable_scissor_test(context_t* c, int enable); -static void ggl_enable_alpha_test(context_t* c, int enable); -static void ggl_enable_logic_op(context_t* c, int enable); -static void ggl_enable_dither(context_t* c, int enable); -static void ggl_enable_stencil_test(context_t* c, int enable); -static void ggl_enable_depth_test(context_t* c, int enable); -static void ggl_enable_aa(context_t* c, int enable); -static void ggl_enable_point_aa_nice(context_t* c, int enable); -static void ggl_enable_texture2d(context_t* c, int enable); -static void ggl_enable_w_lerp(context_t* c, int enable); -static void ggl_enable_fog(context_t* c, int enable); - -static inline int min(int a, int b) CONST; -static inline int min(int a, int b) { - return a < b ? a : b; -} - -static inline int max(int a, int b) CONST; -static inline int max(int a, int b) { - return a < b ? b : a; -} - -// ---------------------------------------------------------------------------- - -void ggl_error(context_t* c, GGLenum error) -{ - if (c->error == GGL_NO_ERROR) - c->error = error; -} - -// ---------------------------------------------------------------------------- - -static void ggl_bindTexture(void* con, const GGLSurface* surface) -{ - GGL_CONTEXT(c, con); - if (surface->format != c->activeTMU->surface.format) - ggl_state_changed(c, GGL_TMU_STATE); - ggl_set_surface(c, &(c->activeTMU->surface), surface); -} - - -static void ggl_bindTextureLod(void* con, GGLuint tmu,const GGLSurface* surface) -{ - GGL_CONTEXT(c, con); - // All LODs must have the same format - ggl_set_surface(c, &c->state.texture[tmu].surface, surface); -} - -static void ggl_colorBuffer(void* con, const GGLSurface* surface) -{ - GGL_CONTEXT(c, con); - if (surface->format != c->state.buffers.color.format) - ggl_state_changed(c, GGL_CB_STATE); - - if (surface->width > c->state.buffers.coverageBufferSize) { - // allocate the coverage factor buffer - free(c->state.buffers.coverage); - c->state.buffers.coverage = (int16_t*)malloc(surface->width * 2); - c->state.buffers.coverageBufferSize = - c->state.buffers.coverage ? surface->width : 0; - } - ggl_set_surface(c, &(c->state.buffers.color), surface); - if (c->state.buffers.read.format == 0) { - ggl_set_surface(c, &(c->state.buffers.read), surface); - } - ggl_set_scissor(c); -} - -static void ggl_readBuffer(void* con, const GGLSurface* surface) -{ - GGL_CONTEXT(c, con); - ggl_set_surface(c, &(c->state.buffers.read), surface); -} - -static void ggl_depthBuffer(void* con, const GGLSurface* surface) -{ - GGL_CONTEXT(c, con); - if (surface->format == GGL_PIXEL_FORMAT_Z_16) { - ggl_set_surface(c, &(c->state.buffers.depth), surface); - } else { - c->state.buffers.depth.format = GGL_PIXEL_FORMAT_NONE; - ggl_enable_depth_test(c, 0); - } -} - -static void ggl_scissor(void* con, GGLint x, GGLint y, - GGLsizei width, GGLsizei height) -{ - GGL_CONTEXT(c, con); - c->state.scissor.user_left = x; - c->state.scissor.user_top = y; - c->state.scissor.user_right = x + width; - c->state.scissor.user_bottom = y + height; - ggl_set_scissor(c); -} - -// ---------------------------------------------------------------------------- - -static void enable_disable(context_t* c, GGLenum name, int en) -{ - switch (name) { - case GGL_BLEND: ggl_enable_blending(c, en); break; - case GGL_SCISSOR_TEST: ggl_enable_scissor_test(c, en); break; - case GGL_ALPHA_TEST: ggl_enable_alpha_test(c, en); break; - case GGL_COLOR_LOGIC_OP: ggl_enable_logic_op(c, en); break; - case GGL_DITHER: ggl_enable_dither(c, en); break; - case GGL_STENCIL_TEST: ggl_enable_stencil_test(c, en); break; - case GGL_DEPTH_TEST: ggl_enable_depth_test(c, en); break; - case GGL_AA: ggl_enable_aa(c, en); break; - case GGL_TEXTURE_2D: ggl_enable_texture2d(c, en); break; - case GGL_W_LERP: ggl_enable_w_lerp(c, en); break; - case GGL_FOG: ggl_enable_fog(c, en); break; - case GGL_POINT_SMOOTH_NICE: ggl_enable_point_aa_nice(c, en); break; - } -} - -static void ggl_enable(void* con, GGLenum name) -{ - GGL_CONTEXT(c, con); - enable_disable(c, name, 1); -} - -static void ggl_disable(void* con, GGLenum name) -{ - GGL_CONTEXT(c, con); - enable_disable(c, name, 0); -} - -static void ggl_enableDisable(void* con, GGLenum name, GGLboolean en) -{ - GGL_CONTEXT(c, con); - enable_disable(c, name, en ? 1 : 0); -} - -// ---------------------------------------------------------------------------- - -static void ggl_shadeModel(void* con, GGLenum mode) -{ - GGL_CONTEXT(c, con); - switch (mode) { - case GGL_FLAT: - if (c->state.enables & GGL_ENABLE_SMOOTH) { - c->state.enables &= ~GGL_ENABLE_SMOOTH; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } - break; - case GGL_SMOOTH: - if (!(c->state.enables & GGL_ENABLE_SMOOTH)) { - c->state.enables |= GGL_ENABLE_SMOOTH; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } - break; - default: - ggl_error(c, GGL_INVALID_ENUM); - } -} - -static void ggl_color4xv(void* con, const GGLclampx* color) -{ - GGL_CONTEXT(c, con); - c->shade.r0 = gglFixedToIteratedColor(color[0]); - c->shade.g0 = gglFixedToIteratedColor(color[1]); - c->shade.b0 = gglFixedToIteratedColor(color[2]); - c->shade.a0 = gglFixedToIteratedColor(color[3]); -} - -static void ggl_colorGrad12xv(void* con, const GGLcolor* grad) -{ - GGL_CONTEXT(c, con); - // it is very important to round the iterated value here because - // the rasterizer doesn't clamp them, therefore the iterated value - //must absolutely be correct. - // GGLColor is encoded as 8.16 value - const int32_t round = 0x8000; - c->shade.r0 = grad[ 0] + round; - c->shade.drdx = grad[ 1]; - c->shade.drdy = grad[ 2]; - c->shade.g0 = grad[ 3] + round; - c->shade.dgdx = grad[ 4]; - c->shade.dgdy = grad[ 5]; - c->shade.b0 = grad[ 6] + round; - c->shade.dbdx = grad[ 7]; - c->shade.dbdy = grad[ 8]; - c->shade.a0 = grad[ 9] + round; - c->shade.dadx = grad[10]; - c->shade.dady = grad[11]; -} - -static void ggl_zGrad3xv(void* con, const GGLfixed32* grad) -{ - GGL_CONTEXT(c, con); - // z iterators are encoded as 0.32 fixed point and the z-buffer - // holds 16 bits, the rounding value is 0x8000. - const uint32_t round = 0x8000; - c->shade.z0 = grad[0] + round; - c->shade.dzdx = grad[1]; - c->shade.dzdy = grad[2]; -} - -static void ggl_wGrad3xv(void* con, const GGLfixed* grad) -{ - GGL_CONTEXT(c, con); - c->shade.w0 = grad[0]; - c->shade.dwdx = grad[1]; - c->shade.dwdy = grad[2]; -} - -// ---------------------------------------------------------------------------- - -static void ggl_fogGrad3xv(void* con, const GGLfixed* grad) -{ - GGL_CONTEXT(c, con); - c->shade.f0 = grad[0]; - c->shade.dfdx = grad[1]; - c->shade.dfdy = grad[2]; -} - -static void ggl_fogColor3xv(void* con, const GGLclampx* color) -{ - GGL_CONTEXT(c, con); - const int32_t r = gglClampx(color[0]); - const int32_t g = gglClampx(color[1]); - const int32_t b = gglClampx(color[2]); - c->state.fog.color[GGLFormat::RED] = (r - (r>>8))>>8; - c->state.fog.color[GGLFormat::GREEN]= (g - (g>>8))>>8; - c->state.fog.color[GGLFormat::BLUE] = (b - (b>>8))>>8; -} - -static void ggl_enable_fog(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_FOG)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_FOG; - else c->state.enables &= ~GGL_ENABLE_FOG; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -// ---------------------------------------------------------------------------- - -static void ggl_blendFunc(void* con, GGLenum src, GGLenum dst) -{ - GGL_CONTEXT(c, con); - c->state.blend.src = src; - c->state.blend.src_alpha = src; - c->state.blend.dst = dst; - c->state.blend.dst_alpha = dst; - c->state.blend.alpha_separate = 0; - if (c->state.enables & GGL_ENABLE_BLENDING) { - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -static void ggl_blendFuncSeparate(void* con, - GGLenum src, GGLenum dst, - GGLenum srcAlpha, GGLenum dstAplha) -{ - GGL_CONTEXT(c, con); - c->state.blend.src = src; - c->state.blend.src_alpha = srcAlpha; - c->state.blend.dst = dst; - c->state.blend.dst_alpha = dstAplha; - c->state.blend.alpha_separate = 1; - if (c->state.enables & GGL_ENABLE_BLENDING) { - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -// ---------------------------------------------------------------------------- - -static void ggl_texEnvi(void* con, GGLenum target, - GGLenum pname, - GGLint param) -{ - GGL_CONTEXT(c, con); - if (target != GGL_TEXTURE_ENV || pname != GGL_TEXTURE_ENV_MODE) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - switch (param) { - case GGL_REPLACE: - case GGL_MODULATE: - case GGL_DECAL: - case GGL_BLEND: - case GGL_ADD: - if (c->activeTMU->env != param) { - c->activeTMU->env = param; - ggl_state_changed(c, GGL_TMU_STATE); - } - break; - default: - ggl_error(c, GGL_INVALID_ENUM); - } -} - -static void ggl_texEnvxv(void* con, GGLenum target, - GGLenum pname, const GGLfixed* params) -{ - GGL_CONTEXT(c, con); - if (target != GGL_TEXTURE_ENV) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - switch (pname) { - case GGL_TEXTURE_ENV_MODE: - ggl_texEnvi(con, target, pname, params[0]); - break; - case GGL_TEXTURE_ENV_COLOR: { - uint8_t* const color = c->activeTMU->env_color; - const GGLclampx r = gglClampx(params[0]); - const GGLclampx g = gglClampx(params[1]); - const GGLclampx b = gglClampx(params[2]); - const GGLclampx a = gglClampx(params[3]); - color[0] = (a-(a>>8))>>8; - color[1] = (r-(r>>8))>>8; - color[2] = (g-(g>>8))>>8; - color[3] = (b-(b>>8))>>8; - break; - } - default: - ggl_error(c, GGL_INVALID_ENUM); - return; - } -} - - -static void ggl_texParameteri(void* con, - GGLenum target, - GGLenum pname, - GGLint param) -{ - GGL_CONTEXT(c, con); - if (target != GGL_TEXTURE_2D) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - - if (param == GGL_CLAMP_TO_EDGE) - param = GGL_CLAMP; - - uint16_t* what = 0; - switch (pname) { - case GGL_TEXTURE_WRAP_S: - if ((param == GGL_CLAMP) || - (param == GGL_REPEAT)) { - what = &c->activeTMU->s_wrap; - } - break; - case GGL_TEXTURE_WRAP_T: - if ((param == GGL_CLAMP) || - (param == GGL_REPEAT)) { - what = &c->activeTMU->t_wrap; - } - break; - case GGL_TEXTURE_MIN_FILTER: - if ((param == GGL_NEAREST) || - (param == GGL_NEAREST_MIPMAP_NEAREST) || - (param == GGL_NEAREST_MIPMAP_LINEAR)) { - what = &c->activeTMU->min_filter; - param = GGL_NEAREST; - } - if ((param == GGL_LINEAR) || - (param == GGL_LINEAR_MIPMAP_NEAREST) || - (param == GGL_LINEAR_MIPMAP_LINEAR)) { - what = &c->activeTMU->min_filter; - param = GGL_LINEAR; - } - break; - case GGL_TEXTURE_MAG_FILTER: - if ((param == GGL_NEAREST) || - (param == GGL_LINEAR)) { - what = &c->activeTMU->mag_filter; - } - break; - } - - if (!what) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - - if (*what != param) { - *what = param; - ggl_state_changed(c, GGL_TMU_STATE); - } -} - -static void ggl_texCoordGradScale8xv(void* con, GGLint tmu, const int32_t* grad) -{ - GGL_CONTEXT(c, con); - texture_t& u = c->state.texture[tmu]; - u.shade.is0 = grad[0]; - u.shade.idsdx = grad[1]; - u.shade.idsdy = grad[2]; - u.shade.it0 = grad[3]; - u.shade.idtdx = grad[4]; - u.shade.idtdy = grad[5]; - u.shade.sscale= grad[6]; - u.shade.tscale= grad[7]; -} - -static void ggl_texCoord2x(void* con, GGLfixed s, GGLfixed t) -{ - GGL_CONTEXT(c, con); - c->activeTMU->shade.is0 = s; - c->activeTMU->shade.it0 = t; - c->activeTMU->shade.sscale= 0; - c->activeTMU->shade.tscale= 0; -} - -static void ggl_texCoord2i(void* con, GGLint s, GGLint t) -{ - ggl_texCoord2x(con, s<<16, t<<16); -} - -static void ggl_texGeni(void* con, GGLenum coord, GGLenum pname, GGLint param) -{ - GGL_CONTEXT(c, con); - if (pname != GGL_TEXTURE_GEN_MODE) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - - uint32_t* coord_ptr = 0; - if (coord == GGL_S) coord_ptr = &(c->activeTMU->s_coord); - else if (coord == GGL_T) coord_ptr = &(c->activeTMU->t_coord); - - if (coord_ptr) { - if (*coord_ptr != uint32_t(param)) { - *coord_ptr = uint32_t(param); - ggl_state_changed(c, GGL_TMU_STATE); - } - } else { - ggl_error(c, GGL_INVALID_ENUM); - } -} - -static void ggl_activeTexture(void* con, GGLuint tmu) -{ - GGL_CONTEXT(c, con); - if (tmu >= GGLuint(GGL_TEXTURE_UNIT_COUNT)) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - c->activeTMUIndex = tmu; - c->activeTMU = &(c->state.texture[tmu]); -} - -// ---------------------------------------------------------------------------- - -static void ggl_colorMask(void* con, GGLboolean r, - GGLboolean g, - GGLboolean b, - GGLboolean a) -{ - GGL_CONTEXT(c, con); - int mask = 0; - if (a) mask |= 1 << GGLFormat::ALPHA; - if (r) mask |= 1 << GGLFormat::RED; - if (g) mask |= 1 << GGLFormat::GREEN; - if (b) mask |= 1 << GGLFormat::BLUE; - if (c->state.mask.color != mask) { - c->state.mask.color = mask; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -static void ggl_depthMask(void* con, GGLboolean flag) -{ - GGL_CONTEXT(c, con); - if (c->state.mask.depth != flag?1:0) { - c->state.mask.depth = flag?1:0; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -static void ggl_stencilMask(void* con, GGLuint mask) -{ - GGL_CONTEXT(c, con); - if (c->state.mask.stencil != mask) { - c->state.mask.stencil = mask; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -// ---------------------------------------------------------------------------- - -static void ggl_alphaFuncx(void* con, GGLenum func, GGLclampx ref) -{ - GGL_CONTEXT(c, con); - if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - c->state.alpha_test.ref = gglFixedToIteratedColor(gglClampx(ref)); - if (c->state.alpha_test.func != func) { - c->state.alpha_test.func = func; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -// ---------------------------------------------------------------------------- - -static void ggl_depthFunc(void* con, GGLenum func) -{ - GGL_CONTEXT(c, con); - if ((func < GGL_NEVER) || (func > GGL_ALWAYS)) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - if (c->state.depth_test.func != func) { - c->state.depth_test.func = func; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -// ---------------------------------------------------------------------------- - -static void ggl_logicOp(void* con, GGLenum opcode) -{ - GGL_CONTEXT(c, con); - if ((opcode < GGL_CLEAR) || (opcode > GGL_SET)) { - ggl_error(c, GGL_INVALID_ENUM); - return; - } - if (c->state.logic_op.opcode != opcode) { - c->state.logic_op.opcode = opcode; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - - -// ---------------------------------------------------------------------------- - -void ggl_set_scissor(context_t* c) -{ - if (c->state.enables & GGL_ENABLE_SCISSOR_TEST) { - const int32_t l = c->state.scissor.user_left; - const int32_t t = c->state.scissor.user_top; - const int32_t r = c->state.scissor.user_right; - const int32_t b = c->state.scissor.user_bottom; - c->state.scissor.left = max(0, l); - c->state.scissor.right = min(c->state.buffers.color.width, r); - c->state.scissor.top = max(0, t); - c->state.scissor.bottom = min(c->state.buffers.color.height, b); - } else { - c->state.scissor.left = 0; - c->state.scissor.top = 0; - c->state.scissor.right = c->state.buffers.color.width; - c->state.scissor.bottom = c->state.buffers.color.height; - } -} - -void ggl_enable_blending(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_BLENDING)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_BLENDING; - else c->state.enables &= ~GGL_ENABLE_BLENDING; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_scissor_test(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_SCISSOR_TEST)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_SCISSOR_TEST; - else c->state.enables &= ~GGL_ENABLE_SCISSOR_TEST; - ggl_set_scissor(c); - } -} - -void ggl_enable_alpha_test(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_ALPHA_TEST)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_ALPHA_TEST; - else c->state.enables &= ~GGL_ENABLE_ALPHA_TEST; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_logic_op(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_LOGIC_OP)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_LOGIC_OP; - else c->state.enables &= ~GGL_ENABLE_LOGIC_OP; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_dither(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_DITHER)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_DITHER; - else c->state.enables &= ~GGL_ENABLE_DITHER; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_stencil_test(context_t* c, int enable) -{ -} - -void ggl_enable_depth_test(context_t* c, int enable) -{ - if (c->state.buffers.depth.format == 0) - enable = 0; - const int e = (c->state.enables & GGL_ENABLE_DEPTH_TEST)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_DEPTH_TEST; - else c->state.enables &= ~GGL_ENABLE_DEPTH_TEST; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_aa(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_AA)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_AA; - else c->state.enables &= ~GGL_ENABLE_AA; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_point_aa_nice(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_POINT_AA_NICE)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_POINT_AA_NICE; - else c->state.enables &= ~GGL_ENABLE_POINT_AA_NICE; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_w_lerp(context_t* c, int enable) -{ - const int e = (c->state.enables & GGL_ENABLE_W)?1:0; - if (e != enable) { - if (enable) c->state.enables |= GGL_ENABLE_W; - else c->state.enables &= ~GGL_ENABLE_W; - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE); - } -} - -void ggl_enable_texture2d(context_t* c, int enable) -{ - if (c->activeTMU->enable != enable) { - const uint32_t tmu = c->activeTMUIndex; - c->activeTMU->enable = enable; - const uint32_t mask = 1UL << tmu; - if (enable) c->state.enabled_tmu |= mask; - else c->state.enabled_tmu &= ~mask; - if (c->state.enabled_tmu) c->state.enables |= GGL_ENABLE_TMUS; - else c->state.enables &= ~GGL_ENABLE_TMUS; - ggl_state_changed(c, GGL_TMU_STATE); - } -} - - -// ---------------------------------------------------------------------------- - -int64_t ggl_system_time() -{ -#if defined(HAVE_POSIX_CLOCKS) - struct timespec t; - t.tv_sec = t.tv_nsec = 0; - clock_gettime(CLOCK_THREAD_CPUTIME_ID, &t); - return int64_t(t.tv_sec)*1000000000LL + t.tv_nsec; -#else - // we don't support the clocks here. - struct timeval t; - t.tv_sec = t.tv_usec = 0; - gettimeofday(&t, NULL); - return int64_t(t.tv_sec)*1000000000LL + int64_t(t.tv_usec)*1000LL; -#endif -} - -// ---------------------------------------------------------------------------- - -void ggl_init_procs(context_t* c) -{ - GGLContext& procs = *(GGLContext*)c; - GGL_INIT_PROC(procs, scissor); - GGL_INIT_PROC(procs, activeTexture); - GGL_INIT_PROC(procs, bindTexture); - GGL_INIT_PROC(procs, bindTextureLod); - GGL_INIT_PROC(procs, colorBuffer); - GGL_INIT_PROC(procs, readBuffer); - GGL_INIT_PROC(procs, depthBuffer); - GGL_INIT_PROC(procs, enable); - GGL_INIT_PROC(procs, disable); - GGL_INIT_PROC(procs, enableDisable); - GGL_INIT_PROC(procs, shadeModel); - GGL_INIT_PROC(procs, color4xv); - GGL_INIT_PROC(procs, colorGrad12xv); - GGL_INIT_PROC(procs, zGrad3xv); - GGL_INIT_PROC(procs, wGrad3xv); - GGL_INIT_PROC(procs, fogGrad3xv); - GGL_INIT_PROC(procs, fogColor3xv); - GGL_INIT_PROC(procs, blendFunc); - GGL_INIT_PROC(procs, blendFuncSeparate); - GGL_INIT_PROC(procs, texEnvi); - GGL_INIT_PROC(procs, texEnvxv); - GGL_INIT_PROC(procs, texParameteri); - GGL_INIT_PROC(procs, texCoord2i); - GGL_INIT_PROC(procs, texCoord2x); - GGL_INIT_PROC(procs, texCoordGradScale8xv); - GGL_INIT_PROC(procs, texGeni); - GGL_INIT_PROC(procs, colorMask); - GGL_INIT_PROC(procs, depthMask); - GGL_INIT_PROC(procs, stencilMask); - GGL_INIT_PROC(procs, alphaFuncx); - GGL_INIT_PROC(procs, depthFunc); - GGL_INIT_PROC(procs, logicOp); - ggl_init_clear(c); -} - -void ggl_init_context(context_t* c) -{ - memset(c, 0, sizeof(context_t)); - ggl_init_procs(c); - ggl_init_trap(c); - ggl_init_scanline(c); - ggl_init_texture(c); - ggl_init_picker(c); - ggl_init_raster(c); - c->formats = gglGetPixelFormatTable(); - c->state.blend.src = GGL_ONE; - c->state.blend.dst = GGL_ZERO; - c->state.blend.src_alpha = GGL_ONE; - c->state.blend.dst_alpha = GGL_ZERO; - c->state.mask.color = 0xF; - c->state.mask.depth = 0; - c->state.mask.stencil = 0xFFFFFFFF; - c->state.logic_op.opcode = GGL_COPY; - c->state.alpha_test.func = GGL_ALWAYS; - c->state.depth_test.func = GGL_LESS; - c->state.depth_test.clearValue = FIXED_ONE; - c->shade.w0 = FIXED_ONE; - memcpy(c->ditherMatrix, gDitherMatrix, sizeof(gDitherMatrix)); -} - -void ggl_uninit_context(context_t* c) -{ - ggl_uninit_scanline(c); -} - -// ---------------------------------------------------------------------------- -}; // namespace android -// ---------------------------------------------------------------------------- - - - -using namespace android; - -ssize_t gglInit(GGLContext** context) -{ - void* const base = malloc(sizeof(context_t) + 32); - if (base) { - // always align the context on cache lines - context_t *c = (context_t *)((ptrdiff_t(base)+31) & ~0x1FL); - ggl_init_context(c); - c->base = base; - *context = (GGLContext*)c; - } else { - return -1; - } - return 0; -} - -ssize_t gglUninit(GGLContext* con) -{ - GGL_CONTEXT(c, (void*)con); - ggl_uninit_context(c); - free(c->base); - return 0; -} - diff --git a/libpixelflinger/raster.cpp b/libpixelflinger/raster.cpp deleted file mode 100644 index d751202945aaa5d6264df497c096a7569e81ed9b..0000000000000000000000000000000000000000 --- a/libpixelflinger/raster.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* libs/pixelflinger/raster.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - - -#include <string.h> - -#include "raster.h" -#include "trap.h" - -namespace android { - -static void ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y); -static void ggl_rasterPos2i(void* con, GGLint x, GGLint y); -static void ggl_copyPixels(void* con, GGLint xs, GGLint ys, - GGLsizei width, GGLsizei height, GGLenum type); - -void ggl_init_raster(context_t* c) -{ - GGLContext& procs = *(GGLContext*)c; - GGL_INIT_PROC(procs, copyPixels); - GGL_INIT_PROC(procs, rasterPos2x); - GGL_INIT_PROC(procs, rasterPos2i); -} - -void ggl_rasterPos2x(void* con, GGLfixed x, GGLfixed y) -{ - GGL_CONTEXT(c, con); - // raster pos should be processed just like glVertex - c->state.raster.x = x; - c->state.raster.y = y; -} - -void ggl_rasterPos2i(void* con, GGLint x, GGLint y) -{ - ggl_rasterPos2x(con, gglIntToFixed(x), gglIntToFixed(y)); -} - -void ggl_copyPixels(void* con, GGLint xs, GGLint ys, - GGLsizei width, GGLsizei height, GGLenum type) -{ - GGL_CONTEXT(c, con); - - // color-buffer - surface_t* cb = &(c->state.buffers.color); - - // undefined behaviour if we try to copy from outside the surface - if (uint32_t(xs) > cb->width) - return; - if (uint32_t(ys) > cb->height) - return; - if (uint32_t(xs + width) > cb->width) - return; - if (uint32_t(ys + height) > cb->height) - return; - - // copy to current raster position - GGLint xd = gglFixedToIntRound(c->state.raster.x); - GGLint yd = gglFixedToIntRound(c->state.raster.y); - - // clip to scissor - if (xd < GGLint(c->state.scissor.left)) { - GGLint offset = GGLint(c->state.scissor.left) - xd; - xd = GGLint(c->state.scissor.left); - xs += offset; - width -= offset; - } - if (yd < GGLint(c->state.scissor.top)) { - GGLint offset = GGLint(c->state.scissor.top) - yd; - yd = GGLint(c->state.scissor.top); - ys += offset; - height -= offset; - } - if ((xd + width) > GGLint(c->state.scissor.right)) { - width = GGLint(c->state.scissor.right) - xd; - } - if ((yd + height) > GGLint(c->state.scissor.bottom)) { - height = GGLint(c->state.scissor.bottom) - yd; - } - - if (width<=0 || height<=0) { - return; // nothing to copy - } - - if (xs==xd && ys==yd) { - // nothing to do, but be careful, this might not be true when we support - // gglPixelTransfer, gglPixelMap and gglPixelZoom - return; - } - - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* src = reinterpret_cast<uint8_t*>(cb->data) - + (xs + (cb->stride * ys)) * fp->size; - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) - + (xd + (cb->stride * yd)) * fp->size; - const size_t bpr = cb->stride * fp->size; - const size_t rowsize = width * fp->size; - size_t yc = height; - - if (ys < yd) { - // bottom to top - src += height * bpr; - dst += height * bpr; - do { - dst -= bpr; - src -= bpr; - memcpy(dst, src, rowsize); - } while (--yc); - } else { - if (ys == yd) { - // might be right to left - do { - memmove(dst, src, rowsize); - dst += bpr; - src += bpr; - } while (--yc); - } else { - // top to bottom - do { - memcpy(dst, src, rowsize); - dst += bpr; - src += bpr; - } while (--yc); - } - } -} - -}; // namespace android - -using namespace android; - -GGLint gglBitBlti(GGLContext* con, int tmu, GGLint crop[4], GGLint where[4]) -{ - GGL_CONTEXT(c, (void*)con); - - GGLint x = where[0]; - GGLint y = where[1]; - GGLint w = where[2]; - GGLint h = where[3]; - - // exclsively enable this tmu - const GGLSurface& cbSurface = c->state.buffers.color.s; - c->procs.activeTexture(c, tmu); - c->procs.disable(c, GGL_W_LERP); - - uint32_t tmus = 1UL<<tmu; - if (c->state.enabled_tmu != tmus) { - c->activeTMU->enable = 1; - c->state.enabled_tmu = tmus; - c->state.enables |= GGL_ENABLE_TMUS; - ggl_state_changed(c, GGL_TMU_STATE); - } - - const GGLint Wcr = crop[2]; - const GGLint Hcr = crop[3]; - if ((w == Wcr) && (h == Hcr)) { - c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); - c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_ONE_TO_ONE); - const GGLint Ucr = crop[0]; - const GGLint Vcr = crop[1]; - const GGLint s0 = Ucr - x; - const GGLint t0 = Vcr - y; - c->procs.texCoord2i(c, s0, t0); - c->procs.recti(c, x, y, x+w, y+h); - } else { - int32_t texcoords[8]; - x = gglIntToFixed(x); - y = gglIntToFixed(y); - - // we CLAMP here, which works with premultiplied (s,t) - c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_S, GGL_CLAMP); - c->procs.texParameteri(c, GGL_TEXTURE_2D, GGL_TEXTURE_WRAP_T, GGL_CLAMP); - c->procs.texGeni(c, GGL_S, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); - c->procs.texGeni(c, GGL_T, GGL_TEXTURE_GEN_MODE, GGL_AUTOMATIC); - - const GGLint Ucr = crop[0] << 16; - const GGLint Vcr = crop[1] << 16; - const GGLint Wcr = crop[2] << 16; - const GGLint Hcr = crop[3] << 16; - - // computes texture coordinates (pre-multiplied) - int32_t dsdx = Wcr / w; // dsdx = ((Wcr/w)/Wt)*Wt - int32_t dtdy = Hcr / h; // dtdy = ((Hcr/h)/Ht)*Ht - int32_t s0 = Ucr - gglMulx(dsdx, x); // s0 = Ucr - x * dsdx - int32_t t0 = Vcr - gglMulx(dtdy, y); // t0 = Vcr - y * dtdy - texcoords[0] = s0; - texcoords[1] = dsdx; - texcoords[2] = 0; - texcoords[3] = t0; - texcoords[4] = 0; - texcoords[5] = dtdy; - texcoords[6] = 0; - texcoords[7] = 0; - c->procs.texCoordGradScale8xv(c, tmu, texcoords); - c->procs.recti(c, - gglFixedToIntRound(x), - gglFixedToIntRound(y), - gglFixedToIntRound(x)+w, - gglFixedToIntRound(y)+h); - } - return 0; -} - diff --git a/libpixelflinger/raster.h b/libpixelflinger/raster.h deleted file mode 100644 index 9f0f240aaea0058faf2e0698301bd0f1fa005a9b..0000000000000000000000000000000000000000 --- a/libpixelflinger/raster.h +++ /dev/null @@ -1,33 +0,0 @@ -/* libs/pixelflinger/raster.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_GGL_RASTER_H -#define ANDROID_GGL_RASTER_H - -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_raster(context_t* c); - -void gglCopyPixels(void* c, GGLint x, GGLint y, GGLsizei width, GGLsizei height, GGLenum type); -void gglRasterPos2d(void* c, GGLint x, GGLint y); - -}; // namespace android - -#endif // ANDROID_GGL_RASTER_H diff --git a/libpixelflinger/rotate90CW_4x4_16v6.S b/libpixelflinger/rotate90CW_4x4_16v6.S deleted file mode 100644 index 8e3e142c07fee4488493e5b4243c4ed921ef28bd..0000000000000000000000000000000000000000 --- a/libpixelflinger/rotate90CW_4x4_16v6.S +++ /dev/null @@ -1,62 +0,0 @@ -/* -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - - .text - .align - - .global rotate90CW_4x4_16v6 - -// Rotates 90deg CW a 4x4 block of 16bpp pixels using ARMv6 -// src and dst must be 4 pixels-aligned (2-pixels aligned might -// actually work) -// -// The code below is complicated by ARM's little endianness. - -rotate90CW_4x4_16v6: - // r0 = dst - // r1 = src - // r2 = dst stride in pixels - // r3 = src stride in pixels - - stmfd sp!, {r4,r5, r6,r7, r8,r9, r10,r11, lr} - add r14, r3, r3 - add r12, r2, r2 - - ldrd r2, r3, [r1], r14 - ldrd r4, r5, [r1], r14 - ldrd r6, r7, [r1], r14 - ldrd r8, r9, [r1] - - pkhbt r10, r8, r6, lsl #16 - pkhbt r11, r4, r2, lsl #16 - strd r10, r11, [r0], r12 - - pkhtb r10, r6, r8, asr #16 - pkhtb r11, r2, r4, asr #16 - - strd r10, r11, [r0], r12 - pkhbt r10, r9, r7, lsl #16 - pkhbt r11, r5, r3, lsl #16 - - strd r10, r11, [r0], r12 - - pkhtb r10, r7, r9, asr #16 - pkhtb r11, r3, r5, asr #16 - strd r10, r11, [r0] - - ldmfd sp!, {r4,r5, r6,r7, r8,r9, r10,r11, pc} diff --git a/libpixelflinger/scanline.cpp b/libpixelflinger/scanline.cpp deleted file mode 100644 index f700306806982d8606ecb9f6f7caf79204658d75..0000000000000000000000000000000000000000 --- a/libpixelflinger/scanline.cpp +++ /dev/null @@ -1,1496 +0,0 @@ -/* libs/pixelflinger/scanline.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#define LOG_TAG "pixelflinger" - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <cutils/memory.h> -#include <cutils/log.h> - -#include "buffer.h" -#include "scanline.h" - -#include "codeflinger/CodeCache.h" -#include "codeflinger/GGLAssembler.h" -#include "codeflinger/ARMAssembler.h" -//#include "codeflinger/ARMAssemblerOptimizer.h" - -// ---------------------------------------------------------------------------- - -#define ANDROID_CODEGEN_GENERIC 0 // force generic pixel pipeline -#define ANDROID_CODEGEN_C 1 // hand-written C, fallback generic -#define ANDROID_CODEGEN_ASM 2 // hand-written asm, fallback generic -#define ANDROID_CODEGEN_GENERATED 3 // hand-written asm, fallback codegen - -#ifdef NDEBUG -# define ANDROID_RELEASE -# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED -#else -# define ANDROID_DEBUG -# define ANDROID_CODEGEN ANDROID_CODEGEN_GENERATED -#endif - -#if defined(__arm__) -# define ANDROID_ARM_CODEGEN 1 -#else -# define ANDROID_ARM_CODEGEN 0 -#endif - -#define DEBUG__CODEGEN_ONLY 0 - - -#define ASSEMBLY_SCRATCH_SIZE 2048 - -// ---------------------------------------------------------------------------- -namespace android { -// ---------------------------------------------------------------------------- - -static void init_y(context_t*, int32_t); -static void init_y_noop(context_t*, int32_t); -static void init_y_packed(context_t*, int32_t); -static void init_y_error(context_t*, int32_t); - -static void step_y__generic(context_t* c); -static void step_y__nop(context_t*); -static void step_y__smooth(context_t* c); -static void step_y__tmu(context_t* c); -static void step_y__w(context_t* c); - -static void scanline(context_t* c); -static void scanline_perspective(context_t* c); -static void scanline_perspective_single(context_t* c); -static void scanline_t32cb16blend(context_t* c); -static void scanline_t32cb16(context_t* c); -static void scanline_memcpy(context_t* c); -static void scanline_memset8(context_t* c); -static void scanline_memset16(context_t* c); -static void scanline_memset32(context_t* c); -static void scanline_noop(context_t* c); -static void scanline_set(context_t* c); -static void scanline_clear(context_t* c); - -static void rect_generic(context_t* c, size_t yc); -static void rect_memcpy(context_t* c, size_t yc); - -extern "C" void scanline_t32cb16blend_arm(uint16_t*, uint32_t*, size_t); -extern "C" void scanline_t32cb16_arm(uint16_t *dst, uint32_t *src, size_t ct); - -// ---------------------------------------------------------------------------- - -struct shortcut_t { - needs_filter_t filter; - const char* desc; - void (*scanline)(context_t*); - void (*init_y)(context_t*, int32_t); -}; - -// Keep in sync with needs -static shortcut_t shortcuts[] = { - { { { 0x03515104, 0x00000077, { 0x00000A01, 0x00000000 } }, - { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0x0000003F } } }, - "565 fb, 8888 tx, blend", scanline_t32cb16blend, init_y_noop }, - { { { 0x03010104, 0x00000077, { 0x00000A01, 0x00000000 } }, - { 0xFFFFFFFF, 0xFFFFFFFF, { 0xFFFFFFFF, 0x0000003F } } }, - "565 fb, 8888 tx", scanline_t32cb16, init_y_noop }, - { { { 0x00000000, 0x00000000, { 0x00000000, 0x00000000 } }, - { 0x00000000, 0x00000007, { 0x00000000, 0x00000000 } } }, - "(nop) alpha test", scanline_noop, init_y_noop }, - { { { 0x00000000, 0x00000000, { 0x00000000, 0x00000000 } }, - { 0x00000000, 0x00000070, { 0x00000000, 0x00000000 } } }, - "(nop) depth test", scanline_noop, init_y_noop }, - { { { 0x05000000, 0x00000000, { 0x00000000, 0x00000000 } }, - { 0x0F000000, 0x00000080, { 0x00000000, 0x00000000 } } }, - "(nop) logic_op", scanline_noop, init_y_noop }, - { { { 0xF0000000, 0x00000000, { 0x00000000, 0x00000000 } }, - { 0xF0000000, 0x00000080, { 0x00000000, 0x00000000 } } }, - "(nop) color mask", scanline_noop, init_y_noop }, - { { { 0x0F000000, 0x00000077, { 0x00000000, 0x00000000 } }, - { 0xFF000000, 0x000000F7, { 0x00000000, 0x00000000 } } }, - "(set) logic_op", scanline_set, init_y_noop }, - { { { 0x00000000, 0x00000077, { 0x00000000, 0x00000000 } }, - { 0xFF000000, 0x000000F7, { 0x00000000, 0x00000000 } } }, - "(clear) logic_op", scanline_clear, init_y_noop }, - { { { 0x03000000, 0x00000077, { 0x00000000, 0x00000000 } }, - { 0xFFFFFF00, 0x000000F7, { 0x00000000, 0x00000000 } } }, - "(clear) blending 0/0", scanline_clear, init_y_noop }, - { { { 0x00000000, 0x00000000, { 0x00000000, 0x00000000 } }, - { 0x0000003F, 0x00000000, { 0x00000000, 0x00000000 } } }, - "(error) invalid color-buffer format", scanline_noop, init_y_error }, -}; -static const needs_filter_t noblend1to1 = { - // (disregard dithering, see below) - { 0x03010100, 0x00000077, { 0x00000A00, 0x00000000 } }, - { 0xFFFFFFC0, 0xFFFFFEFF, { 0xFFFFFFC0, 0x0000003F } } -}; -static const needs_filter_t fill16noblend = { - { 0x03010100, 0x00000077, { 0x00000000, 0x00000000 } }, - { 0xFFFFFFC0, 0xFFFFFFFF, { 0x0000003F, 0x0000003F } } -}; - -// ---------------------------------------------------------------------------- - -#if ANDROID_ARM_CODEGEN -static CodeCache gCodeCache(12 * 1024); - -class ScanlineAssembly : public Assembly { - AssemblyKey<needs_t> mKey; -public: - ScanlineAssembly(needs_t needs, size_t size) - : Assembly(size), mKey(needs) { } - const AssemblyKey<needs_t>& key() const { return mKey; } -}; -#endif - -// ---------------------------------------------------------------------------- - -void ggl_init_scanline(context_t* c) -{ - c->init_y = init_y; - c->step_y = step_y__generic; - c->scanline = scanline; -} - -void ggl_uninit_scanline(context_t* c) -{ - if (c->state.buffers.coverage) - free(c->state.buffers.coverage); -#if ANDROID_ARM_CODEGEN - if (c->scanline_as) - c->scanline_as->decStrong(c); -#endif -} - -// ---------------------------------------------------------------------------- - -static void pick_scanline(context_t* c) -{ -#if (!defined(DEBUG__CODEGEN_ONLY) || (DEBUG__CODEGEN_ONLY == 0)) - -#if ANDROID_CODEGEN == ANDROID_CODEGEN_GENERIC - c->init_y = init_y; - c->step_y = step_y__generic; - c->scanline = scanline; - return; -#endif - - //printf("*** needs [%08lx:%08lx:%08lx:%08lx]\n", - // c->state.needs.n, c->state.needs.p, - // c->state.needs.t[0], c->state.needs.t[1]); - - // first handle the special case that we cannot test with a filter - const uint32_t cb_format = GGL_READ_NEEDS(CB_FORMAT, c->state.needs.n); - if (GGL_READ_NEEDS(T_FORMAT, c->state.needs.t[0]) == cb_format) { - if (c->state.needs.match(noblend1to1)) { - // this will match regardless of dithering state, since both - // src and dest have the same format anyway, there is no dithering - // to be done. - const GGLFormat* f = - &(c->formats[GGL_READ_NEEDS(T_FORMAT, c->state.needs.t[0])]); - if ((f->components == GGL_RGB) || - (f->components == GGL_RGBA) || - (f->components == GGL_LUMINANCE) || - (f->components == GGL_LUMINANCE_ALPHA)) - { - // format must have all of RGB components - // (so the current color doesn't show through) - c->scanline = scanline_memcpy; - c->init_y = init_y_noop; - return; - } - } - } - - if (c->state.needs.match(fill16noblend)) { - c->init_y = init_y_packed; - switch (c->formats[cb_format].size) { - case 1: c->scanline = scanline_memset8; return; - case 2: c->scanline = scanline_memset16; return; - case 4: c->scanline = scanline_memset32; return; - } - } - - const int numFilters = sizeof(shortcuts)/sizeof(shortcut_t); - for (int i=0 ; i<numFilters ; i++) { - if (c->state.needs.match(shortcuts[i].filter)) { - c->scanline = shortcuts[i].scanline; - c->init_y = shortcuts[i].init_y; - return; - } - } - -#endif // DEBUG__CODEGEN_ONLY - - c->init_y = init_y; - c->step_y = step_y__generic; - -#if ANDROID_ARM_CODEGEN - // we're going to have to generate some code... - // here, generate code for our pixel pipeline - const AssemblyKey<needs_t> key(c->state.needs); - sp<Assembly> assembly = gCodeCache.lookup(key); - if (assembly == 0) { - // create a new assembly region - sp<ScanlineAssembly> a = new ScanlineAssembly(c->state.needs, - ASSEMBLY_SCRATCH_SIZE); - // initialize our assembler - GGLAssembler assembler( new ARMAssembler(a) ); - //GGLAssembler assembler( - // new ARMAssemblerOptimizer(new ARMAssembler(a)) ); - // generate the scanline code for the given needs - int err = assembler.scanline(c->state.needs, c); - if (ggl_likely(!err)) { - // finally, cache this assembly - err = gCodeCache.cache(a->key(), a); - } - if (ggl_unlikely(err)) { - LOGE("error generating or caching assembly. Reverting to NOP."); - c->scanline = scanline_noop; - c->init_y = init_y_noop; - c->step_y = step_y__nop; - return; - } - assembly = a; - } - - // release the previous assembly - if (c->scanline_as) { - c->scanline_as->decStrong(c); - } - - //LOGI("using generated pixel-pipeline"); - c->scanline_as = assembly.get(); - c->scanline_as->incStrong(c); // hold on to assembly - c->scanline = (void(*)(context_t* c))assembly->base(); -#else -// LOGW("using generic (slow) pixel-pipeline"); - c->scanline = scanline; -#endif -} - -void ggl_pick_scanline(context_t* c) -{ - pick_scanline(c); - if ((c->state.enables & GGL_ENABLE_W) && - (c->state.enables & GGL_ENABLE_TMUS)) - { - c->span = c->scanline; - c->scanline = scanline_perspective; - if (!(c->state.enabled_tmu & (c->state.enabled_tmu - 1))) { - // only one TMU enabled - c->scanline = scanline_perspective_single; - } - } -} - -// ---------------------------------------------------------------------------- - -static void blending(context_t* c, pixel_t* fragment, pixel_t* fb); -static void blend_factor(context_t* c, pixel_t* r, uint32_t factor, - const pixel_t* src, const pixel_t* dst); -static void rescale(uint32_t& u, uint8_t& su, uint32_t& v, uint8_t& sv); - -#if ANDROID_ARM_CODEGEN && (ANDROID_CODEGEN == ANDROID_CODEGEN_GENERATED) - -// no need to compile the generic-pipeline, it can't be reached -void scanline(context_t*) -{ -} - -#else - -void rescale(uint32_t& u, uint8_t& su, uint32_t& v, uint8_t& sv) -{ - if (su && sv) { - if (su > sv) { - v = ggl_expand(v, sv, su); - sv = su; - } else if (su < sv) { - u = ggl_expand(u, su, sv); - su = sv; - } - } -} - -void blending(context_t* c, pixel_t* fragment, pixel_t* fb) -{ - rescale(fragment->c[0], fragment->s[0], fb->c[0], fb->s[0]); - rescale(fragment->c[1], fragment->s[1], fb->c[1], fb->s[1]); - rescale(fragment->c[2], fragment->s[2], fb->c[2], fb->s[2]); - rescale(fragment->c[3], fragment->s[3], fb->c[3], fb->s[3]); - - pixel_t sf, df; - blend_factor(c, &sf, c->state.blend.src, fragment, fb); - blend_factor(c, &df, c->state.blend.dst, fragment, fb); - - fragment->c[1] = - gglMulAddx(fragment->c[1], sf.c[1], gglMulx(fb->c[1], df.c[1])); - fragment->c[2] = - gglMulAddx(fragment->c[2], sf.c[2], gglMulx(fb->c[2], df.c[2])); - fragment->c[3] = - gglMulAddx(fragment->c[3], sf.c[3], gglMulx(fb->c[3], df.c[3])); - - if (c->state.blend.alpha_separate) { - blend_factor(c, &sf, c->state.blend.src_alpha, fragment, fb); - blend_factor(c, &df, c->state.blend.dst_alpha, fragment, fb); - } - - fragment->c[0] = - gglMulAddx(fragment->c[0], sf.c[0], gglMulx(fb->c[0], df.c[0])); - - // clamp to 1.0 - if (fragment->c[0] >= (1LU<<fragment->s[0])) - fragment->c[0] = (1<<fragment->s[0])-1; - if (fragment->c[1] >= (1LU<<fragment->s[1])) - fragment->c[1] = (1<<fragment->s[1])-1; - if (fragment->c[2] >= (1LU<<fragment->s[2])) - fragment->c[2] = (1<<fragment->s[2])-1; - if (fragment->c[3] >= (1LU<<fragment->s[3])) - fragment->c[3] = (1<<fragment->s[3])-1; -} - -static inline int blendfactor(uint32_t x, uint32_t size, uint32_t def = 0) -{ - if (!size) - return def; - - // scale to 16 bits - if (size > 16) { - x >>= (size - 16); - } else if (size < 16) { - x = ggl_expand(x, size, 16); - } - x += x >> 15; - return x; -} - -void blend_factor(context_t* c, pixel_t* r, - uint32_t factor, const pixel_t* src, const pixel_t* dst) -{ - switch (factor) { - case GGL_ZERO: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = 0; - break; - case GGL_ONE: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = FIXED_ONE; - break; - case GGL_DST_COLOR: - r->c[1] = blendfactor(dst->c[1], dst->s[1]); - r->c[2] = blendfactor(dst->c[2], dst->s[2]); - r->c[3] = blendfactor(dst->c[3], dst->s[3]); - r->c[0] = blendfactor(dst->c[0], dst->s[0]); - break; - case GGL_SRC_COLOR: - r->c[1] = blendfactor(src->c[1], src->s[1]); - r->c[2] = blendfactor(src->c[2], src->s[2]); - r->c[3] = blendfactor(src->c[3], src->s[3]); - r->c[0] = blendfactor(src->c[0], src->s[0]); - break; - case GGL_ONE_MINUS_DST_COLOR: - r->c[1] = FIXED_ONE - blendfactor(dst->c[1], dst->s[1]); - r->c[2] = FIXED_ONE - blendfactor(dst->c[2], dst->s[2]); - r->c[3] = FIXED_ONE - blendfactor(dst->c[3], dst->s[3]); - r->c[0] = FIXED_ONE - blendfactor(dst->c[0], dst->s[0]); - break; - case GGL_ONE_MINUS_SRC_COLOR: - r->c[1] = FIXED_ONE - blendfactor(src->c[1], src->s[1]); - r->c[2] = FIXED_ONE - blendfactor(src->c[2], src->s[2]); - r->c[3] = FIXED_ONE - blendfactor(src->c[3], src->s[3]); - r->c[0] = FIXED_ONE - blendfactor(src->c[0], src->s[0]); - break; - case GGL_SRC_ALPHA: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = blendfactor(src->c[0], src->s[0], FIXED_ONE); - break; - case GGL_ONE_MINUS_SRC_ALPHA: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = FIXED_ONE - blendfactor(src->c[0], src->s[0], FIXED_ONE); - break; - case GGL_DST_ALPHA: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = blendfactor(dst->c[0], dst->s[0], FIXED_ONE); - break; - case GGL_ONE_MINUS_DST_ALPHA: - r->c[1] = - r->c[2] = - r->c[3] = - r->c[0] = FIXED_ONE - blendfactor(dst->c[0], dst->s[0], FIXED_ONE); - break; - case GGL_SRC_ALPHA_SATURATE: - // XXX: GGL_SRC_ALPHA_SATURATE - break; - } -} - -static GGLfixed wrapping(int32_t coord, uint32_t size, int tx_wrap) -{ - GGLfixed d; - if (tx_wrap == GGL_REPEAT) { - d = (uint32_t(coord)>>16) * size; - } else if (tx_wrap == GGL_CLAMP) { // CLAMP_TO_EDGE semantics - const GGLfixed clamp_min = FIXED_HALF; - const GGLfixed clamp_max = (size << 16) - FIXED_HALF; - if (coord < clamp_min) coord = clamp_min; - if (coord > clamp_max) coord = clamp_max; - d = coord; - } else { // 1:1 - const GGLfixed clamp_min = 0; - const GGLfixed clamp_max = (size << 16); - if (coord < clamp_min) coord = clamp_min; - if (coord > clamp_max) coord = clamp_max; - d = coord; - } - return d; -} - -static inline -GGLcolor ADJUST_COLOR_ITERATOR(GGLcolor v, GGLcolor dvdx, int len) -{ - const int32_t end = dvdx * (len-1) + v; - if (end < 0) - v -= end; - v &= ~(v>>31); - return v; -} - -void scanline(context_t* c) -{ - const uint32_t enables = c->state.enables; - const int xs = c->iterators.xl; - const int x1 = c->iterators.xr; - int xc = x1 - xs; - const int16_t* covPtr = c->state.buffers.coverage + xs; - - // All iterated values are sampled at the pixel center - - // reset iterators for that scanline... - GGLcolor r, g, b, a; - iterators_t& ci = c->iterators; - if (enables & GGL_ENABLE_SMOOTH) { - r = (xs * c->shade.drdx) + ci.ydrdy; - g = (xs * c->shade.dgdx) + ci.ydgdy; - b = (xs * c->shade.dbdx) + ci.ydbdy; - a = (xs * c->shade.dadx) + ci.ydady; - r = ADJUST_COLOR_ITERATOR(r, c->shade.drdx, xc); - g = ADJUST_COLOR_ITERATOR(g, c->shade.dgdx, xc); - b = ADJUST_COLOR_ITERATOR(b, c->shade.dbdx, xc); - a = ADJUST_COLOR_ITERATOR(a, c->shade.dadx, xc); - } else { - r = ci.ydrdy; - g = ci.ydgdy; - b = ci.ydbdy; - a = ci.ydady; - } - - // z iterators are 1.31 - GGLfixed z = (xs * c->shade.dzdx) + ci.ydzdy; - GGLfixed f = (xs * c->shade.dfdx) + ci.ydfdy; - - struct { - GGLfixed s, t; - } tc[GGL_TEXTURE_UNIT_COUNT]; - if (enables & GGL_ENABLE_TMUS) { - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - if (c->state.texture[i].enable) { - texture_iterators_t& ti = c->state.texture[i].iterators; - if (enables & GGL_ENABLE_W) { - tc[i].s = ti.ydsdy; - tc[i].t = ti.ydtdy; - } else { - tc[i].s = (xs * ti.dsdx) + ti.ydsdy; - tc[i].t = (xs * ti.dtdx) + ti.ydtdy; - } - } - } - } - - pixel_t fragment; - pixel_t texel; - pixel_t fb; - - uint32_t x = xs; - uint32_t y = c->iterators.y; - - while (xc--) { - - { // just a scope - - // read color (convert to 8 bits by keeping only the integer part) - fragment.s[1] = fragment.s[2] = - fragment.s[3] = fragment.s[0] = 8; - fragment.c[1] = r >> (GGL_COLOR_BITS-8); - fragment.c[2] = g >> (GGL_COLOR_BITS-8); - fragment.c[3] = b >> (GGL_COLOR_BITS-8); - fragment.c[0] = a >> (GGL_COLOR_BITS-8); - - // texturing - if (enables & GGL_ENABLE_TMUS) { - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - texture_t& tx = c->state.texture[i]; - if (!tx.enable) - continue; - texture_iterators_t& ti = tx.iterators; - int32_t u, v; - - // s-coordinate - if (tx.s_coord != GGL_ONE_TO_ONE) { - const int w = tx.surface.width; - u = wrapping(tc[i].s, w, tx.s_wrap); - tc[i].s += ti.dsdx; - } else { - u = (((tx.shade.is0>>16) + x)<<16) + FIXED_HALF; - } - - // t-coordinate - if (tx.t_coord != GGL_ONE_TO_ONE) { - const int h = tx.surface.height; - v = wrapping(tc[i].t, h, tx.t_wrap); - tc[i].t += ti.dtdx; - } else { - v = (((tx.shade.it0>>16) + y)<<16) + FIXED_HALF; - } - - // read texture - if (tx.mag_filter == GGL_NEAREST && - tx.min_filter == GGL_NEAREST) - { - u >>= 16; - v >>= 16; - tx.surface.read(&tx.surface, c, u, v, &texel); - } else { - const int w = tx.surface.width; - const int h = tx.surface.height; - u -= FIXED_HALF; - v -= FIXED_HALF; - int u0 = u >> 16; - int v0 = v >> 16; - int u1 = u0 + 1; - int v1 = v0 + 1; - if (tx.s_wrap == GGL_REPEAT) { - if (u0<0) u0 += w; - if (u1<0) u1 += w; - if (u0>=w) u0 -= w; - if (u1>=w) u1 -= w; - } else { - if (u0<0) u0 = 0; - if (u1<0) u1 = 0; - if (u0>=w) u0 = w-1; - if (u1>=w) u1 = w-1; - } - if (tx.t_wrap == GGL_REPEAT) { - if (v0<0) v0 += h; - if (v1<0) v1 += h; - if (v0>=h) v0 -= h; - if (v1>=h) v1 -= h; - } else { - if (v0<0) v0 = 0; - if (v1<0) v1 = 0; - if (v0>=h) v0 = h-1; - if (v1>=h) v1 = h-1; - } - pixel_t texels[4]; - uint32_t mm[4]; - tx.surface.read(&tx.surface, c, u0, v0, &texels[0]); - tx.surface.read(&tx.surface, c, u0, v1, &texels[1]); - tx.surface.read(&tx.surface, c, u1, v0, &texels[2]); - tx.surface.read(&tx.surface, c, u1, v1, &texels[3]); - u = (u >> 12) & 0xF; - v = (v >> 12) & 0xF; - u += u>>3; - v += v>>3; - mm[0] = (0x10 - u) * (0x10 - v); - mm[1] = (0x10 - u) * v; - mm[2] = u * (0x10 - v); - mm[3] = 0x100 - (mm[0] + mm[1] + mm[2]); - for (int j=0 ; j<4 ; j++) { - texel.s[j] = texels[0].s[j]; - if (!texel.s[j]) continue; - texel.s[j] += 8; - texel.c[j] = texels[0].c[j]*mm[0] + - texels[1].c[j]*mm[1] + - texels[2].c[j]*mm[2] + - texels[3].c[j]*mm[3] ; - } - } - - // Texture environnement... - for (int j=0 ; j<4 ; j++) { - uint32_t& Cf = fragment.c[j]; - uint32_t& Ct = texel.c[j]; - uint8_t& sf = fragment.s[j]; - uint8_t& st = texel.s[j]; - uint32_t At = texel.c[0]; - uint8_t sat = texel.s[0]; - switch (tx.env) { - case GGL_REPLACE: - if (st) { - Cf = Ct; - sf = st; - } - break; - case GGL_MODULATE: - if (st) { - uint32_t factor = Ct + (Ct>>(st-1)); - Cf = (Cf * factor) >> st; - } - break; - case GGL_DECAL: - if (sat) { - rescale(Cf, sf, Ct, st); - Cf += ((Ct - Cf) * (At + (At>>(sat-1)))) >> sat; - } - break; - case GGL_BLEND: - if (st) { - uint32_t Cc = tx.env_color[i]; - if (sf>8) Cc = (Cc * ((1<<sf)-1))>>8; - else if (sf<8) Cc = (Cc - (Cc>>(8-sf)))>>(8-sf); - uint32_t factor = Ct + (Ct>>(st-1)); - Cf = ((((1<<st) - factor) * Cf) + Ct*Cc)>>st; - } - break; - case GGL_ADD: - if (st) { - rescale(Cf, sf, Ct, st); - Cf += Ct; - } - break; - } - } - } - } - - // coverage application - if (enables & GGL_ENABLE_AA) { - int16_t cf = *covPtr++; - fragment.c[0] = (int64_t(fragment.c[0]) * cf) >> 15; - } - - // alpha-test - if (enables & GGL_ENABLE_ALPHA_TEST) { - GGLcolor ref = c->state.alpha_test.ref; - GGLcolor alpha = (uint64_t(fragment.c[0]) * - ((1<<GGL_COLOR_BITS)-1)) / ((1<<fragment.s[0])-1); - switch (c->state.alpha_test.func) { - case GGL_NEVER: goto discard; - case GGL_LESS: if (alpha<ref) break; goto discard; - case GGL_EQUAL: if (alpha==ref) break; goto discard; - case GGL_LEQUAL: if (alpha<=ref) break; goto discard; - case GGL_GREATER: if (alpha>ref) break; goto discard; - case GGL_NOTEQUAL: if (alpha!=ref) break; goto discard; - case GGL_GEQUAL: if (alpha>=ref) break; goto discard; - } - } - - // depth test - if (c->state.buffers.depth.format) { - if (enables & GGL_ENABLE_DEPTH_TEST) { - surface_t* cb = &(c->state.buffers.depth); - uint16_t* p = (uint16_t*)(cb->data)+(x+(cb->stride*y)); - uint16_t zz = uint32_t(z)>>(16); - uint16_t depth = *p; - switch (c->state.depth_test.func) { - case GGL_NEVER: goto discard; - case GGL_LESS: if (zz<depth) break; goto discard; - case GGL_EQUAL: if (zz==depth) break; goto discard; - case GGL_LEQUAL: if (zz<=depth) break; goto discard; - case GGL_GREATER: if (zz>depth) break; goto discard; - case GGL_NOTEQUAL: if (zz!=depth) break; goto discard; - case GGL_GEQUAL: if (zz>=depth) break; goto discard; - } - // depth buffer is not enabled, if depth-test is not enabled -/* - fragment.s[1] = fragment.s[2] = - fragment.s[3] = fragment.s[0] = 8; - fragment.c[1] = - fragment.c[2] = - fragment.c[3] = - fragment.c[0] = 255 - (zz>>8); -*/ - if (c->state.mask.depth) { - *p = zz; - } - } - } - - // fog - if (enables & GGL_ENABLE_FOG) { - for (int i=1 ; i<=3 ; i++) { - GGLfixed fc = (c->state.fog.color[i] * 0x10000) / 0xFF; - uint32_t& c = fragment.c[i]; - uint8_t& s = fragment.s[i]; - c = (c * 0x10000) / ((1<<s)-1); - c = gglMulAddx(c, f, gglMulx(fc, 0x10000 - f)); - s = 16; - } - } - - // blending - if (enables & GGL_ENABLE_BLENDING) { - fb.c[1] = fb.c[2] = fb.c[3] = fb.c[0] = 0; // placate valgrind - fb.s[1] = fb.s[2] = fb.s[3] = fb.s[0] = 0; - c->state.buffers.color.read( - &(c->state.buffers.color), c, x, y, &fb); - blending( c, &fragment, &fb ); - } - - // write - c->state.buffers.color.write( - &(c->state.buffers.color), c, x, y, &fragment); - } - -discard: - // iterate... - x += 1; - if (enables & GGL_ENABLE_SMOOTH) { - r += c->shade.drdx; - g += c->shade.dgdx; - b += c->shade.dbdx; - a += c->shade.dadx; - } - z += c->shade.dzdx; - f += c->shade.dfdx; - } -} - -#endif // ANDROID_ARM_CODEGEN && (ANDROID_CODEGEN == ANDROID_CODEGEN_GENERATED) - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Scanline -#endif - -template <typename T, typename U> -static inline __attribute__((const)) -T interpolate(int y, T v0, U dvdx, U dvdy) { - // interpolates in pixel's centers - // v = v0 + (y + 0.5) * dvdy + (0.5 * dvdx) - return (y * dvdy) + (v0 + ((dvdy + dvdx) >> 1)); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -void init_y(context_t* c, int32_t ys) -{ - const uint32_t enables = c->state.enables; - - // compute iterators... - iterators_t& ci = c->iterators; - - // sample in the center - ci.y = ys; - - if (enables & (GGL_ENABLE_DEPTH_TEST|GGL_ENABLE_W|GGL_ENABLE_FOG)) { - ci.ydzdy = interpolate(ys, c->shade.z0, c->shade.dzdx, c->shade.dzdy); - ci.ydwdy = interpolate(ys, c->shade.w0, c->shade.dwdx, c->shade.dwdy); - ci.ydfdy = interpolate(ys, c->shade.f0, c->shade.dfdx, c->shade.dfdy); - } - - if (ggl_unlikely(enables & GGL_ENABLE_SMOOTH)) { - ci.ydrdy = interpolate(ys, c->shade.r0, c->shade.drdx, c->shade.drdy); - ci.ydgdy = interpolate(ys, c->shade.g0, c->shade.dgdx, c->shade.dgdy); - ci.ydbdy = interpolate(ys, c->shade.b0, c->shade.dbdx, c->shade.dbdy); - ci.ydady = interpolate(ys, c->shade.a0, c->shade.dadx, c->shade.dady); - c->step_y = step_y__smooth; - } else { - ci.ydrdy = c->shade.r0; - ci.ydgdy = c->shade.g0; - ci.ydbdy = c->shade.b0; - ci.ydady = c->shade.a0; - // XXX: do only if needed, or make sure this is fast - c->packed = ggl_pack_color(c, c->state.buffers.color.format, - ci.ydrdy, ci.ydgdy, ci.ydbdy, ci.ydady); - c->packed8888 = ggl_pack_color(c, GGL_PIXEL_FORMAT_RGBA_8888, - ci.ydrdy, ci.ydgdy, ci.ydbdy, ci.ydady); - } - - // initialize the variables we need in the shader - generated_vars_t& gen = c->generated_vars; - gen.argb[GGLFormat::ALPHA].c = ci.ydady; - gen.argb[GGLFormat::ALPHA].dx = c->shade.dadx; - gen.argb[GGLFormat::RED ].c = ci.ydrdy; - gen.argb[GGLFormat::RED ].dx = c->shade.drdx; - gen.argb[GGLFormat::GREEN].c = ci.ydgdy; - gen.argb[GGLFormat::GREEN].dx = c->shade.dgdx; - gen.argb[GGLFormat::BLUE ].c = ci.ydbdy; - gen.argb[GGLFormat::BLUE ].dx = c->shade.dbdx; - gen.dzdx = c->shade.dzdx; - gen.f = ci.ydfdy; - gen.dfdx = c->shade.dfdx; - - if (enables & GGL_ENABLE_TMUS) { - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - texture_t& t = c->state.texture[i]; - if (!t.enable) continue; - - texture_iterators_t& ti = t.iterators; - if (t.s_coord == GGL_ONE_TO_ONE && t.t_coord == GGL_ONE_TO_ONE) { - // we need to set all of these to 0 because in some cases - // step_y__generic() or step_y__tmu() will be used and - // therefore will update dtdy, however, in 1:1 mode - // this is always done by the scanline rasterizer. - ti.dsdx = ti.dsdy = ti.dtdx = ti.dtdy = 0; - ti.ydsdy = t.shade.is0; - ti.ydtdy = t.shade.it0; - } else { - const int adjustSWrap = ((t.s_wrap==GGL_CLAMP)?0:16); - const int adjustTWrap = ((t.t_wrap==GGL_CLAMP)?0:16); - ti.sscale = t.shade.sscale + adjustSWrap; - ti.tscale = t.shade.tscale + adjustTWrap; - if (!(enables & GGL_ENABLE_W)) { - // S coordinate - const int32_t sscale = ti.sscale; - const int32_t sy = interpolate(ys, - t.shade.is0, t.shade.idsdx, t.shade.idsdy); - if (sscale>=0) { - ti.ydsdy= sy << sscale; - ti.dsdx = t.shade.idsdx << sscale; - ti.dsdy = t.shade.idsdy << sscale; - } else { - ti.ydsdy= sy >> -sscale; - ti.dsdx = t.shade.idsdx >> -sscale; - ti.dsdy = t.shade.idsdy >> -sscale; - } - // T coordinate - const int32_t tscale = ti.tscale; - const int32_t ty = interpolate(ys, - t.shade.it0, t.shade.idtdx, t.shade.idtdy); - if (tscale>=0) { - ti.ydtdy= ty << tscale; - ti.dtdx = t.shade.idtdx << tscale; - ti.dtdy = t.shade.idtdy << tscale; - } else { - ti.ydtdy= ty >> -tscale; - ti.dtdx = t.shade.idtdx >> -tscale; - ti.dtdy = t.shade.idtdy >> -tscale; - } - } - } - // mirror for generated code... - generated_tex_vars_t& gen = c->generated_vars.texture[i]; - gen.width = t.surface.width; - gen.height = t.surface.height; - gen.stride = t.surface.stride; - gen.data = int32_t(t.surface.data); - gen.dsdx = ti.dsdx; - gen.dtdx = ti.dtdx; - } - } - - // choose the y-stepper - c->step_y = step_y__nop; - if (enables & GGL_ENABLE_FOG) { - c->step_y = step_y__generic; - } else if (enables & GGL_ENABLE_TMUS) { - if (enables & GGL_ENABLE_SMOOTH) { - c->step_y = step_y__generic; - } else if (enables & GGL_ENABLE_W) { - c->step_y = step_y__w; - } else { - c->step_y = step_y__tmu; - } - } else { - if (enables & GGL_ENABLE_SMOOTH) { - c->step_y = step_y__smooth; - } - } - - // choose the rectangle blitter - c->rect = rect_generic; - if ((c->step_y == step_y__nop) && - (c->scanline == scanline_memcpy)) - { - c->rect = rect_memcpy; - } -} - -void init_y_packed(context_t* c, int32_t y0) -{ - uint8_t f = c->state.buffers.color.format; - c->packed = ggl_pack_color(c, f, - c->shade.r0, c->shade.g0, c->shade.b0, c->shade.a0); - c->iterators.y = y0; - c->step_y = step_y__nop; - // choose the rectangle blitter - c->rect = rect_generic; - if (c->scanline == scanline_memcpy) { - c->rect = rect_memcpy; - } -} - -void init_y_noop(context_t* c, int32_t y0) -{ - c->iterators.y = y0; - c->step_y = step_y__nop; - // choose the rectangle blitter - c->rect = rect_generic; - if (c->scanline == scanline_memcpy) { - c->rect = rect_memcpy; - } -} - -void init_y_error(context_t* c, int32_t y0) -{ - // woooops, shoud never happen, - // fail gracefully (don't display anything) - init_y_noop(c, y0); - LOGE("color-buffer has an invalid format!"); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -void step_y__generic(context_t* c) -{ - const uint32_t enables = c->state.enables; - - // iterate... - iterators_t& ci = c->iterators; - ci.y += 1; - - if (enables & GGL_ENABLE_SMOOTH) { - ci.ydrdy += c->shade.drdy; - ci.ydgdy += c->shade.dgdy; - ci.ydbdy += c->shade.dbdy; - ci.ydady += c->shade.dady; - } - - const uint32_t mask = - GGL_ENABLE_DEPTH_TEST | - GGL_ENABLE_W | - GGL_ENABLE_FOG; - if (enables & mask) { - ci.ydzdy += c->shade.dzdy; - ci.ydwdy += c->shade.dwdy; - ci.ydfdy += c->shade.dfdy; - } - - if ((enables & GGL_ENABLE_TMUS) && (!(enables & GGL_ENABLE_W))) { - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - if (c->state.texture[i].enable) { - texture_iterators_t& ti = c->state.texture[i].iterators; - ti.ydsdy += ti.dsdy; - ti.ydtdy += ti.dtdy; - } - } - } -} - -void step_y__nop(context_t* c) -{ - c->iterators.y += 1; - c->iterators.ydzdy += c->shade.dzdy; -} - -void step_y__smooth(context_t* c) -{ - iterators_t& ci = c->iterators; - ci.y += 1; - ci.ydrdy += c->shade.drdy; - ci.ydgdy += c->shade.dgdy; - ci.ydbdy += c->shade.dbdy; - ci.ydady += c->shade.dady; - ci.ydzdy += c->shade.dzdy; -} - -void step_y__w(context_t* c) -{ - iterators_t& ci = c->iterators; - ci.y += 1; - ci.ydzdy += c->shade.dzdy; - ci.ydwdy += c->shade.dwdy; -} - -void step_y__tmu(context_t* c) -{ - iterators_t& ci = c->iterators; - ci.y += 1; - ci.ydzdy += c->shade.dzdy; - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - if (c->state.texture[i].enable) { - texture_iterators_t& ti = c->state.texture[i].iterators; - ti.ydsdy += ti.dsdy; - ti.ydtdy += ti.dtdy; - } - } -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -void scanline_perspective(context_t* c) -{ - struct { - union { - struct { - int32_t s, sq; - int32_t t, tq; - }; - struct { - int32_t v, q; - } st[2]; - }; - } tc[GGL_TEXTURE_UNIT_COUNT] __attribute__((aligned(16))); - - // XXX: we should have a special case when dwdx = 0 - - // 32 pixels spans works okay. 16 is a lot better, - // but hey, it's a software renderer... - const uint32_t SPAN_BITS = 5; - const uint32_t ys = c->iterators.y; - const uint32_t xs = c->iterators.xl; - const uint32_t x1 = c->iterators.xr; - const uint32_t xc = x1 - xs; - uint32_t remainder = xc & ((1<<SPAN_BITS)-1); - uint32_t numSpans = xc >> SPAN_BITS; - - const iterators_t& ci = c->iterators; - int32_t w0 = (xs * c->shade.dwdx) + ci.ydwdy; - int32_t q0 = gglRecipQ(w0, 30); - const int iwscale = 32 - gglClz(q0); - - const int32_t dwdx = c->shade.dwdx << SPAN_BITS; - int32_t xl = c->iterators.xl; - - // We process s & t with a loop to reduce the code size - // (and i-cache pressure). - - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - const texture_t& tmu = c->state.texture[i]; - if (!tmu.enable) continue; - int32_t s = tmu.shade.is0 + - (tmu.shade.idsdy * ys) + (tmu.shade.idsdx * xs) + - ((tmu.shade.idsdx + tmu.shade.idsdy)>>1); - int32_t t = tmu.shade.it0 + - (tmu.shade.idtdy * ys) + (tmu.shade.idtdx * xs) + - ((tmu.shade.idtdx + tmu.shade.idtdy)>>1); - tc[i].s = s; - tc[i].t = t; - tc[i].sq = gglMulx(s, q0, iwscale); - tc[i].tq = gglMulx(t, q0, iwscale); - } - - int32_t span = 0; - do { - int32_t w1; - if (ggl_likely(numSpans)) { - w1 = w0 + dwdx; - } else { - if (remainder) { - // finish off the scanline... - span = remainder; - w1 = (c->shade.dwdx * span) + w0; - } else { - break; - } - } - int32_t q1 = gglRecipQ(w1, 30); - for (int i=0 ; i<GGL_TEXTURE_UNIT_COUNT ; ++i) { - texture_t& tmu = c->state.texture[i]; - if (!tmu.enable) continue; - texture_iterators_t& ti = tmu.iterators; - - for (int j=0 ; j<2 ; j++) { - int32_t v = tc[i].st[j].v; - if (span) v += (tmu.shade.st[j].dx)*span; - else v += (tmu.shade.st[j].dx)<<SPAN_BITS; - const int32_t v0 = tc[i].st[j].q; - const int32_t v1 = gglMulx(v, q1, iwscale); - int32_t dvdx = v1 - v0; - if (span) dvdx /= span; - else dvdx >>= SPAN_BITS; - tc[i].st[j].v = v; - tc[i].st[j].q = v1; - - const int scale = ti.st[j].scale + (iwscale - 30); - if (scale >= 0) { - ti.st[j].ydvdy = v0 << scale; - ti.st[j].dvdx = dvdx << scale; - } else { - ti.st[j].ydvdy = v0 >> -scale; - ti.st[j].dvdx = dvdx >> -scale; - } - } - generated_tex_vars_t& gen = c->generated_vars.texture[i]; - gen.dsdx = ti.st[0].dvdx; - gen.dtdx = ti.st[1].dvdx; - } - c->iterators.xl = xl; - c->iterators.xr = xl = xl + (span ? span : (1<<SPAN_BITS)); - w0 = w1; - q0 = q1; - c->span(c); - } while(numSpans--); -} - -void scanline_perspective_single(context_t* c) -{ - // 32 pixels spans works okay. 16 is a lot better, - // but hey, it's a software renderer... - const uint32_t SPAN_BITS = 5; - const uint32_t ys = c->iterators.y; - const uint32_t xs = c->iterators.xl; - const uint32_t x1 = c->iterators.xr; - const uint32_t xc = x1 - xs; - - const iterators_t& ci = c->iterators; - int32_t w = (xs * c->shade.dwdx) + ci.ydwdy; - int32_t iw = gglRecipQ(w, 30); - const int iwscale = 32 - gglClz(iw); - - const int i = 31 - gglClz(c->state.enabled_tmu); - generated_tex_vars_t& gen = c->generated_vars.texture[i]; - texture_t& tmu = c->state.texture[i]; - texture_iterators_t& ti = tmu.iterators; - const int sscale = ti.sscale + (iwscale - 30); - const int tscale = ti.tscale + (iwscale - 30); - int32_t s = tmu.shade.is0 + - (tmu.shade.idsdy * ys) + (tmu.shade.idsdx * xs) + - ((tmu.shade.idsdx + tmu.shade.idsdy)>>1); - int32_t t = tmu.shade.it0 + - (tmu.shade.idtdy * ys) + (tmu.shade.idtdx * xs) + - ((tmu.shade.idtdx + tmu.shade.idtdy)>>1); - int32_t s0 = gglMulx(s, iw, iwscale); - int32_t t0 = gglMulx(t, iw, iwscale); - int32_t xl = c->iterators.xl; - - int32_t sq, tq, dsdx, dtdx; - int32_t premainder = xc & ((1<<SPAN_BITS)-1); - uint32_t numSpans = xc >> SPAN_BITS; - if (c->shade.dwdx == 0) { - // XXX: we could choose to do this if the error is small enough - numSpans = 0; - premainder = xc; - goto no_perspective; - } - - if (premainder) { - w += c->shade.dwdx * premainder; - iw = gglRecipQ(w, 30); -no_perspective: - s += tmu.shade.idsdx * premainder; - t += tmu.shade.idtdx * premainder; - sq = gglMulx(s, iw, iwscale); - tq = gglMulx(t, iw, iwscale); - dsdx = (sq - s0) / premainder; - dtdx = (tq - t0) / premainder; - c->iterators.xl = xl; - c->iterators.xr = xl = xl + premainder; - goto finish; - } - - while (numSpans--) { - w += c->shade.dwdx << SPAN_BITS; - s += tmu.shade.idsdx << SPAN_BITS; - t += tmu.shade.idtdx << SPAN_BITS; - iw = gglRecipQ(w, 30); - sq = gglMulx(s, iw, iwscale); - tq = gglMulx(t, iw, iwscale); - dsdx = (sq - s0) >> SPAN_BITS; - dtdx = (tq - t0) >> SPAN_BITS; - c->iterators.xl = xl; - c->iterators.xr = xl = xl + (1<<SPAN_BITS); -finish: - if (sscale >= 0) { - ti.ydsdy = s0 << sscale; - ti.dsdx = dsdx << sscale; - } else { - ti.ydsdy = s0 >>-sscale; - ti.dsdx = dsdx >>-sscale; - } - if (tscale >= 0) { - ti.ydtdy = t0 << tscale; - ti.dtdx = dtdx << tscale; - } else { - ti.ydtdy = t0 >>-tscale; - ti.dtdx = dtdx >>-tscale; - } - s0 = sq; - t0 = tq; - gen.dsdx = ti.dsdx; - gen.dtdx = ti.dtdx; - c->span(c); - } -} - -// ---------------------------------------------------------------------------- - -void scanline_t32cb16(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - union { - uint16_t* dst; - uint32_t* dst32; - }; - dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); - - surface_t* tex = &(c->state.texture[0].surface); - const int32_t u = (c->state.texture[0].shade.is0>>16) + x; - const int32_t v = (c->state.texture[0].shade.it0>>16) + y; - uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v)); - int sR, sG, sB; - uint32_t s, d; - - if (ct==1 || uint32_t(dst)&2) { -last_one: - s = GGL_RGBA_TO_HOST( *src++ ); - sR = (s >> ( 3))&0x1F; - sG = (s >> ( 8+2))&0x3F; - sB = (s >> (16+3))&0x1F; - *dst++ = uint16_t((sR<<11)|(sG<<5)|sB); - ct--; - } - - while (ct >= 2) { - s = GGL_RGBA_TO_HOST( *src++ ); - sR = (s >> ( 3))&0x1F; - sG = (s >> ( 8+2))&0x3F; - sB = (s >> (16+3))&0x1F; - d = (sR<<11)|(sG<<5)|sB; - - s = GGL_RGBA_TO_HOST( *src++ ); - sR = (s >> ( 3))&0x1F; - sG = (s >> ( 8+2))&0x3F; - sB = (s >> (16+3))&0x1F; - d |= ((sR<<11)|(sG<<5)|sB)<<16; - -#if BYTE_ORDER == BIG_ENDIAN - d = (d>>16) | (d<<16); -#endif - - *dst32++ = d; - ct -= 2; - } - - if (ct > 0) { - goto last_one; - } -} - -void scanline_t32cb16blend(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - uint16_t* dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); - - surface_t* tex = &(c->state.texture[0].surface); - const int32_t u = (c->state.texture[0].shade.is0>>16) + x; - const int32_t v = (c->state.texture[0].shade.it0>>16) + y; - uint32_t *src = reinterpret_cast<uint32_t*>(tex->data)+(u+(tex->stride*v)); - -#if ((ANDROID_CODEGEN >= ANDROID_CODEGEN_ASM) && defined(__arm__)) - scanline_t32cb16blend_arm(dst, src, ct); -#else - while (ct--) { - uint32_t s = *src++; - if (!s) { - dst++; - continue; - } - uint16_t d = *dst; - s = GGL_RGBA_TO_HOST(s); - int sR = (s >> ( 3))&0x1F; - int sG = (s >> ( 8+2))&0x3F; - int sB = (s >> (16+3))&0x1F; - int sA = (s>>24); - int f = 0x100 - (sA + (sA>>7)); - int dR = (d>>11)&0x1f; - int dG = (d>>5)&0x3f; - int dB = (d)&0x1f; - sR += (f*dR)>>8; - sG += (f*dG)>>8; - sB += (f*dB)>>8; - *dst++ = uint16_t((sR<<11)|(sG<<5)|sB); - } -#endif -} - -void scanline_memcpy(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + - (x + (cb->stride * y)) * fp->size; - - surface_t* tex = &(c->state.texture[0].surface); - const int32_t u = (c->state.texture[0].shade.is0>>16) + x; - const int32_t v = (c->state.texture[0].shade.it0>>16) + y; - uint8_t *src = reinterpret_cast<uint8_t*>(tex->data) + - (u + (tex->stride * v)) * fp->size; - - const size_t size = ct * fp->size; - memcpy(dst, src, size); -} - -void scanline_memset8(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + (x+(cb->stride*y)); - uint32_t packed = c->packed; - memset(dst, packed, ct); -} - -void scanline_memset16(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - uint16_t* dst = reinterpret_cast<uint16_t*>(cb->data) + (x+(cb->stride*y)); - uint32_t packed = c->packed; - android_memset16(dst, packed, ct*2); -} - -void scanline_memset32(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - uint32_t* dst = reinterpret_cast<uint32_t*>(cb->data) + (x+(cb->stride*y)); - uint32_t packed = GGL_HOST_TO_RGBA(c->packed); - android_memset32(dst, packed, ct*4); -} - -void scanline_clear(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + - (x + (cb->stride * y)) * fp->size; - const size_t size = ct * fp->size; - memset(dst, 0, size); -} - -void scanline_set(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + - (x + (cb->stride * y)) * fp->size; - const size_t size = ct * fp->size; - memset(dst, 0xFF, size); -} - -void scanline_noop(context_t* c) -{ -} - -void rect_generic(context_t* c, size_t yc) -{ - do { - c->scanline(c); - c->step_y(c); - } while (--yc); -} - -void rect_memcpy(context_t* c, size_t yc) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + - (x + (cb->stride * y)) * fp->size; - - surface_t* tex = &(c->state.texture[0].surface); - const int32_t u = (c->state.texture[0].shade.is0>>16) + x; - const int32_t v = (c->state.texture[0].shade.it0>>16) + y; - uint8_t *src = reinterpret_cast<uint8_t*>(tex->data) + - (u + (tex->stride * v)) * fp->size; - - if (cb->stride == tex->stride && ct == size_t(cb->stride)) { - memcpy(dst, src, ct * fp->size * yc); - } else { - const size_t size = ct * fp->size; - const size_t dbpr = cb->stride * fp->size; - const size_t sbpr = tex->stride * fp->size; - do { - memcpy(dst, src, size); - dst += dbpr; - src += sbpr; - } while (--yc); - } -} -// ---------------------------------------------------------------------------- -}; // namespace android - -using namespace android; -extern "C" void ggl_test_codegen(uint32_t n, uint32_t p, uint32_t t0, uint32_t t1) -{ -#if ANDROID_ARM_CODEGEN - GGLContext* c; - gglInit(&c); - needs_t needs; - needs.n = n; - needs.p = p; - needs.t[0] = t0; - needs.t[1] = t1; - sp<ScanlineAssembly> a(new ScanlineAssembly(needs, ASSEMBLY_SCRATCH_SIZE)); - GGLAssembler assembler( new ARMAssembler(a) ); - int err = assembler.scanline(needs, (context_t*)c); - if (err != 0) { - printf("error %08x (%s)\n", err, strerror(-err)); - } - gglUninit(c); -#else - printf("This test runs only on ARM\n"); -#endif -} - diff --git a/libpixelflinger/scanline.h b/libpixelflinger/scanline.h deleted file mode 100644 index b6f4d374675d1e54423e08653da662063152ecf9..0000000000000000000000000000000000000000 --- a/libpixelflinger/scanline.h +++ /dev/null @@ -1,32 +0,0 @@ -/* libs/pixelflinger/scanline.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_SCANLINE_H -#define ANDROID_SCANLINE_H - -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_scanline(context_t* c); -void ggl_uninit_scanline(context_t* c); -void ggl_pick_scanline(context_t* c); - -}; // namespace android - -#endif diff --git a/libpixelflinger/t32cb16blend.S b/libpixelflinger/t32cb16blend.S deleted file mode 100644 index d4b257981aa32b07419725000c72e3be8cbc86c8..0000000000000000000000000000000000000000 --- a/libpixelflinger/t32cb16blend.S +++ /dev/null @@ -1,171 +0,0 @@ -/* libs/pixelflinger/t32cb16blend.S -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - - .text - .align - - .global scanline_t32cb16blend_arm - -// uses r6, r7, lr - -.macro pixel, DREG, SRC, FB, OFFSET - - // SRC = AARRGGBB - mov r7, \SRC, lsr #24 // sA - add r7, r7, r7, lsr #7 // sA + (sA >> 7) - rsb r7, r7, #0x100 // sA = 0x100 - (sA+(sA>>7)) - -1: - -.if \OFFSET - - // red - mov lr, \DREG, lsr #(\OFFSET + 6 + 5) - smulbb lr, r7, lr - mov r6, \SRC, lsr #3 - and r6, r6, #0x1F - add lr, r6, lr, lsr #8 - orr \FB, lr, lsl #(\OFFSET + 11) - - // green - and r6, \DREG, #(0x3F<<(\OFFSET + 5)) - smulbt r6, r7, r6 - mov lr, \SRC, lsr #(8+2) - and lr, lr, #0x3F - add r6, lr, r6, lsr #(5+8) - orr \FB, \FB, r6, lsl #(\OFFSET + 5) - - // blue - and lr, \DREG, #(0x1F << \OFFSET) - smulbt lr, r7, lr - mov r6, \SRC, lsr #(8+8+3) - and r6, r6, #0x1F - add lr, r6, lr, lsr #8 - orr \FB, \FB, lr, lsl #\OFFSET - -.else - - // red - mov lr, \DREG, lsr #(6+5) - and lr, lr, #0x1F - smulbb lr, r7, lr - mov r6, \SRC, lsr #3 - and r6, r6, #0x1F - add lr, r6, lr, lsr #8 - mov \FB, lr, lsl #11 - - // green - and r6, \DREG, #(0x3F<<5) - smulbb r6, r7, r6 - mov lr, \SRC, lsr #(8+2) - and lr, lr, #0x3F - add r6, lr, r6, lsr #(5+8) - orr \FB, \FB, r6, lsl #5 - - // blue - and lr, \DREG, #0x1F - smulbb lr, r7, lr - mov r6, \SRC, lsr #(8+8+3) - and r6, r6, #0x1F - add lr, r6, lr, lsr #8 - orr \FB, \FB, lr - -.endif - - .endm - - -// r0: dst ptr -// r1: src ptr -// r2: count -// r3: d -// r4: s0 -// r5: s1 -// r6: pixel -// r7: pixel -// r8: free -// r9: free -// r10: free -// r11: free -// r12: scratch -// r14: pixel - -scanline_t32cb16blend_arm: - stmfd sp!, {r4-r7, lr} - - pld [r0] - pld [r1] - - // align DST to 32 bits - tst r0, #0x3 - beq aligned - subs r2, r2, #1 - ldmlofd sp!, {r4-r7, lr} // return - bxlo lr - -last: - ldr r4, [r1], #4 - ldrh r3, [r0] - pixel r3, r4, r12, 0 - strh r12, [r0], #2 - -aligned: - subs r2, r2, #2 - blo 9f - - // The main loop is unrolled twice and process 4 pixels -8: ldmia r1!, {r4, r5} - // stream the source - pld [r1, #32] - add r0, r0, #4 - // it's all zero, skip this pixel - orrs r3, r4, r5 - beq 7f - - // load the destination - ldr r3, [r0, #-4] - // stream the destination - pld [r0, #32] - pixel r3, r4, r12, 0 - pixel r3, r5, r12, 16 - // effectively, we're getting write-combining by virtue of the - // cpu's write-back cache. - str r12, [r0, #-4] - - // 2nd iterration of the loop, don't stream anything - subs r2, r2, #2 - movlt r4, r5 - blt 9f - ldmia r1!, {r4, r5} - add r0, r0, #4 - orrs r3, r4, r5 - beq 7f - ldr r3, [r0, #-4] - pixel r3, r4, r12, 0 - pixel r3, r5, r12, 16 - str r12, [r0, #-4] - - -7: subs r2, r2, #2 - bhs 8b - mov r4, r5 - -9: adds r2, r2, #1 - ldmlofd sp!, {r4-r7, lr} // return - bxlo lr - b last diff --git a/libpixelflinger/tests/Android.mk b/libpixelflinger/tests/Android.mk deleted file mode 100644 index 65711611ccc6a3dd7f3a0a08e1438e148ef2d5ce..0000000000000000000000000000000000000000 --- a/libpixelflinger/tests/Android.mk +++ /dev/null @@ -1 +0,0 @@ -include $(all-subdir-makefiles) diff --git a/libpixelflinger/tests/codegen/Android.mk b/libpixelflinger/tests/codegen/Android.mk deleted file mode 100644 index 1bc42148743253064d360deb356b6ea92afa528c..0000000000000000000000000000000000000000 --- a/libpixelflinger/tests/codegen/Android.mk +++ /dev/null @@ -1,15 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - codegen.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libpixelflinger - -LOCAL_MODULE:= test-opengl-codegen - -LOCAL_MODULE_TAGS := tests - -include $(BUILD_EXECUTABLE) diff --git a/libpixelflinger/tests/codegen/codegen.cpp b/libpixelflinger/tests/codegen/codegen.cpp deleted file mode 100644 index 18658881bbf1b1c9452f8a8d35517afc474bc1c1..0000000000000000000000000000000000000000 --- a/libpixelflinger/tests/codegen/codegen.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include <stdio.h> -#include <stdint.h> - -extern "C" void ggl_test_codegen( - uint32_t n, uint32_t p, uint32_t t0, uint32_t t1); - - -int main(int argc, char** argv) -{ - if (argc != 2) { - printf("usage: %s 00000117:03454504_00001501_00000000\n", argv[0]); - return 0; - } - uint32_t n; - uint32_t p; - uint32_t t0; - uint32_t t1; - sscanf(argv[1], "%08x:%08x_%08x_%08x", &p, &n, &t0, &t1); - ggl_test_codegen(n, p, t0, t1); - return 0; -} diff --git a/libpixelflinger/tinyutils/KeyedVector.h b/libpixelflinger/tinyutils/KeyedVector.h deleted file mode 100644 index 1be2094e947eed6cb18524a39c2d2b61080cd864..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/KeyedVector.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * keyed_vector.h - * Android - * - * Created on 11/18/05. - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_KEYED_VECTOR_H -#define ANDROID_KEYED_VECTOR_H - -#include <assert.h> -#include <stdint.h> -#include <sys/types.h> - -#include "tinyutils/SortedVector.h" -#include "tinyutils/TypeHelpers.h" - -// --------------------------------------------------------------------------- - -namespace android { - -template <typename KEY, typename VALUE> -class KeyedVector -{ -public: - typedef KEY key_type; - typedef VALUE value_type; - - inline KeyedVector(); - - /* - * empty the vector - */ - - inline void clear() { mVector.clear(); } - - /*! - * vector stats - */ - - //! returns number of items in the vector - inline size_t size() const { return mVector.size(); } - //! returns wether or not the vector is empty - inline bool isEmpty() const { return mVector.isEmpty(); } - //! returns how many items can be stored without reallocating the backing store - inline size_t capacity() const { return mVector.capacity(); } - //! setst the capacity. capacity can never be reduced less than size() - inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); } - - /*! - * accessors - */ - const VALUE& valueFor(const KEY& key) const; - const VALUE& valueAt(size_t index) const; - const KEY& keyAt(size_t index) const; - ssize_t indexOfKey(const KEY& key) const; - - /*! - * modifing the array - */ - - VALUE& editValueFor(const KEY& key); - VALUE& editValueAt(size_t index); - - /*! - * add/insert/replace items - */ - - ssize_t add(const KEY& key, const VALUE& item); - ssize_t replaceValueFor(const KEY& key, const VALUE& item); - ssize_t replaceValueAt(size_t index, const VALUE& item); - - /*! - * remove items - */ - - ssize_t removeItem(const KEY& key); - ssize_t removeItemsAt(size_t index, size_t count = 1); - -private: - SortedVector< key_value_pair_t<KEY, VALUE> > mVector; -}; - -// --------------------------------------------------------------------------- - -/** - * Variation of KeyedVector that holds a default value to return when - * valueFor() is called with a key that doesn't exist. - */ -template <typename KEY, typename VALUE> -class DefaultKeyedVector : public KeyedVector<KEY, VALUE> -{ -public: - inline DefaultKeyedVector(const VALUE& defValue = VALUE()); - const VALUE& valueFor(const KEY& key) const; - -private: - VALUE mDefault; -}; - -// --------------------------------------------------------------------------- - -template<typename KEY, typename VALUE> inline -KeyedVector<KEY,VALUE>::KeyedVector() -{ -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const { - return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) ); -} - -template<typename KEY, typename VALUE> inline -const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { - ssize_t i = indexOfKey(key); - assert(i>=0); - return mVector.itemAt(i).value; -} - -template<typename KEY, typename VALUE> inline -const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const { - return mVector.itemAt(index).value; -} - -template<typename KEY, typename VALUE> inline -const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const { - return mVector.itemAt(index).key; -} - -template<typename KEY, typename VALUE> inline -VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) { - ssize_t i = indexOfKey(key); - assert(i>=0); - return mVector.editItemAt(i).value; -} - -template<typename KEY, typename VALUE> inline -VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) { - return mVector.editItemAt(index).value; -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) { - return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) ); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) { - key_value_pair_t<KEY,VALUE> pair(key, value); - mVector.remove(pair); - return mVector.add(pair); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) { - if (index<size()) { - mVector.editValueAt(index).value = item; - return index; - } - return BAD_INDEX; -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) { - return mVector.remove(key_value_pair_t<KEY,VALUE>(key)); -} - -template<typename KEY, typename VALUE> inline -ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) { - return mVector.removeItemsAt(index, count); -} - -// --------------------------------------------------------------------------- - -template<typename KEY, typename VALUE> inline -DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue) - : mDefault(defValue) -{ -} - -template<typename KEY, typename VALUE> inline -const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const { - ssize_t i = indexOfKey(key); - return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault; -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_KEYED_VECTOR_H diff --git a/libpixelflinger/tinyutils/SharedBuffer.cpp b/libpixelflinger/tinyutils/SharedBuffer.cpp deleted file mode 100644 index ef781a75c6beeaf2ff4118e695245490496c3181..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/SharedBuffer.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* - * SharedBuffer.cpp - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#include <stdlib.h> -#include <string.h> - -#include <cutils/atomic.h> - -#include "tinyutils/SharedBuffer.h" - -// --------------------------------------------------------------------------- - -namespace android { - -SharedBuffer* SharedBuffer::alloc(size_t size) -{ - SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size)); - if (sb) { - sb->mRefs = 1; - sb->mSize = size; - } - return sb; -} - - -ssize_t SharedBuffer::dealloc(const SharedBuffer* released) -{ - if (released->mRefs != 0) return -1; // XXX: invalid operation - free(const_cast<SharedBuffer*>(released)); - return 0; -} - -SharedBuffer* SharedBuffer::edit() const -{ - if (onlyOwner()) { - return const_cast<SharedBuffer*>(this); - } - SharedBuffer* sb = alloc(mSize); - if (sb) { - memcpy(sb->data(), data(), size()); - release(); - } - return sb; -} - -SharedBuffer* SharedBuffer::editResize(size_t newSize) const -{ - if (onlyOwner()) { - SharedBuffer* buf = const_cast<SharedBuffer*>(this); - if (buf->mSize == newSize) return buf; - buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize); - if (buf != NULL) { - buf->mSize = newSize; - return buf; - } - } - SharedBuffer* sb = alloc(newSize); - if (sb) { - const size_t mySize = mSize; - memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize); - release(); - } - return sb; -} - -SharedBuffer* SharedBuffer::attemptEdit() const -{ - if (onlyOwner()) { - return const_cast<SharedBuffer*>(this); - } - return 0; -} - -SharedBuffer* SharedBuffer::reset(size_t new_size) const -{ - // cheap-o-reset. - SharedBuffer* sb = alloc(new_size); - if (sb) { - release(); - } - return sb; -} - -void SharedBuffer::acquire() const { - android_atomic_inc(&mRefs); -} - -int32_t SharedBuffer::release(uint32_t flags) const -{ - int32_t prev = 1; - if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) { - mRefs = 0; - if ((flags & eKeepStorage) == 0) { - free(const_cast<SharedBuffer*>(this)); - } - } - return prev; -} - - -}; // namespace android diff --git a/libpixelflinger/tinyutils/SharedBuffer.h b/libpixelflinger/tinyutils/SharedBuffer.h deleted file mode 100644 index 9f631213a08694ba9621898a97ad9f9785d2cb22..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/SharedBuffer.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * SharedBuffer.h - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_SHARED_BUFFER_H -#define ANDROID_SHARED_BUFFER_H - -#include <stdint.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- - -namespace android { - -class SharedBuffer -{ -public: - - /* flags to use with release() */ - enum { - eKeepStorage = 0x00000001 - }; - - /*! allocate a buffer of size 'size' and acquire() it. - * call release() to free it. - */ - static SharedBuffer* alloc(size_t size); - - /*! free the memory associated with the SharedBuffer. - * Fails if there are any users associated with this SharedBuffer. - * In other words, the buffer must have been release by all its - * users. - */ - static ssize_t dealloc(const SharedBuffer* released); - - //! get the SharedBuffer from the data pointer - static inline const SharedBuffer* sharedBuffer(const void* data); - - //! access the data for read - inline const void* data() const; - - //! access the data for read/write - inline void* data(); - - //! get size of the buffer - inline size_t size() const; - - //! get back a SharedBuffer object from its data - static inline SharedBuffer* bufferFromData(void* data); - - //! get back a SharedBuffer object from its data - static inline const SharedBuffer* bufferFromData(const void* data); - - //! get the size of a SharedBuffer object from its data - static inline size_t sizeFromData(const void* data); - - //! edit the buffer (get a writtable, or non-const, version of it) - SharedBuffer* edit() const; - - //! edit the buffer, resizing if needed - SharedBuffer* editResize(size_t size) const; - - //! like edit() but fails if a copy is required - SharedBuffer* attemptEdit() const; - - //! resize and edit the buffer, loose it's content. - SharedBuffer* reset(size_t size) const; - - //! acquire/release a reference on this buffer - void acquire() const; - - /*! release a reference on this buffer, with the option of not - * freeing the memory associated with it if it was the last reference - * returns the previous reference count - */ - int32_t release(uint32_t flags = 0) const; - - //! returns wether or not we're the only owner - inline bool onlyOwner() const; - - -private: - inline SharedBuffer() { } - inline ~SharedBuffer() { } - inline SharedBuffer(const SharedBuffer&); - - // 16 bytes. must be sized to preserve correct alingment. - mutable int32_t mRefs; - size_t mSize; - uint32_t mReserved[2]; -}; - -// --------------------------------------------------------------------------- - -const SharedBuffer* SharedBuffer::sharedBuffer(const void* data) { - return data ? reinterpret_cast<const SharedBuffer *>(data)-1 : 0; -} - -const void* SharedBuffer::data() const { - return this + 1; -} - -void* SharedBuffer::data() { - return this + 1; -} - -size_t SharedBuffer::size() const { - return mSize; -} - -SharedBuffer* SharedBuffer::bufferFromData(void* data) -{ - return ((SharedBuffer*)data)-1; -} - -const SharedBuffer* SharedBuffer::bufferFromData(const void* data) -{ - return ((const SharedBuffer*)data)-1; -} - -size_t SharedBuffer::sizeFromData(const void* data) -{ - return (((const SharedBuffer*)data)-1)->mSize; -} - -bool SharedBuffer::onlyOwner() const { - return (mRefs == 1); -} - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_H diff --git a/libpixelflinger/tinyutils/TypeHelpers.h b/libpixelflinger/tinyutils/TypeHelpers.h deleted file mode 100644 index 9500c90444cbc506e1fc76493d3e4eab4a6af496..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/TypeHelpers.h +++ /dev/null @@ -1,245 +0,0 @@ -/* - * TypeHelpers.h - * - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_TYPE_HELPERS_H -#define ANDROID_TYPE_HELPERS_H - -#include <new> -#include <stdint.h> -#include <string.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- - -namespace android { - -/* - * Types traits - */ - -template <typename T> struct trait_trivial_ctor { enum { value = false }; }; -template <typename T> struct trait_trivial_dtor { enum { value = false }; }; -template <typename T> struct trait_trivial_copy { enum { value = false }; }; -template <typename T> struct trait_trivial_assign{ enum { value = false }; }; - -template <typename T> struct trait_pointer { enum { value = false }; }; -template <typename T> struct trait_pointer<T*> { enum { value = true }; }; - -#define ANDROID_BASIC_TYPES_TRAITS( T ) \ - template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = true }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = true }; }; - -#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \ - template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \ - template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \ - template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \ - template<> struct trait_trivial_assign< T >{ enum { value = assign }; }; - -template <typename TYPE> -struct traits { - enum { - is_pointer = trait_pointer<TYPE>::value, - has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value, - has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value, - has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value, - has_trivial_assign = is_pointer || trait_trivial_assign<TYPE>::value - }; -}; - -template <typename T, typename U> -struct aggregate_traits { - enum { - is_pointer = false, - has_trivial_ctor = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor, - has_trivial_dtor = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor, - has_trivial_copy = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy, - has_trivial_assign = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign - }; -}; - -// --------------------------------------------------------------------------- - -/* - * basic types traits - */ - -ANDROID_BASIC_TYPES_TRAITS( void ); -ANDROID_BASIC_TYPES_TRAITS( bool ); -ANDROID_BASIC_TYPES_TRAITS( char ); -ANDROID_BASIC_TYPES_TRAITS( unsigned char ); -ANDROID_BASIC_TYPES_TRAITS( short ); -ANDROID_BASIC_TYPES_TRAITS( unsigned short ); -ANDROID_BASIC_TYPES_TRAITS( int ); -ANDROID_BASIC_TYPES_TRAITS( unsigned int ); -ANDROID_BASIC_TYPES_TRAITS( long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long ); -ANDROID_BASIC_TYPES_TRAITS( long long ); -ANDROID_BASIC_TYPES_TRAITS( unsigned long long ); -ANDROID_BASIC_TYPES_TRAITS( float ); -ANDROID_BASIC_TYPES_TRAITS( double ); - -// --------------------------------------------------------------------------- - - -/* - * compare and order types - */ - -template<typename TYPE> inline -int strictly_order_type(const TYPE& lhs, const TYPE& rhs) { - return (lhs < rhs) ? 1 : 0; -} - -template<typename TYPE> inline -int compare_type(const TYPE& lhs, const TYPE& rhs) { - return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs); -} - -/* - * create, destroy, copy and assign types... - */ - -template<typename TYPE> inline -void construct_type(TYPE* p, size_t n) { - if (!traits<TYPE>::has_trivial_ctor) { - while (n--) { - new(p++) TYPE; - } - } -} - -template<typename TYPE> inline -void destroy_type(TYPE* p, size_t n) { - if (!traits<TYPE>::has_trivial_dtor) { - while (n--) { - p->~TYPE(); - p++; - } - } -} - -template<typename TYPE> inline -void copy_type(TYPE* d, const TYPE* s, size_t n) { - if (!traits<TYPE>::has_trivial_copy) { - while (n--) { - new(d) TYPE(*s); - d++, s++; - } - } else { - memcpy(d,s,n*sizeof(TYPE)); - } -} - -template<typename TYPE> inline -void assign_type(TYPE* d, const TYPE* s, size_t n) { - if (!traits<TYPE>::has_trivial_assign) { - while (n--) { - *d++ = *s++; - } - } else { - memcpy(d,s,n*sizeof(TYPE)); - } -} - -template<typename TYPE> inline -void splat_type(TYPE* where, const TYPE* what, size_t n) { - if (!traits<TYPE>::has_trivial_copy) { - while (n--) { - new(where) TYPE(*what); - where++; - } - } else { - while (n--) { - *where++ = *what; - } - } -} - -template<typename TYPE> inline -void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { - d += n; - s += n; - while (n--) { - --d, --s; - if (!traits<TYPE>::has_trivial_copy) { - new(d) TYPE(*s); - } else { - *d = *s; - } - if (!traits<TYPE>::has_trivial_dtor) { - s->~TYPE(); - } - } - } else { - memmove(d,s,n*sizeof(TYPE)); - } -} - -template<typename TYPE> inline -void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) { - if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) { - while (n--) { - if (!traits<TYPE>::has_trivial_copy) { - new(d) TYPE(*s); - } else { - *d = *s; - } - if (!traits<TYPE>::has_trivial_dtor) { - s->~TYPE(); - } - d++, s++; - } - } else { - memmove(d,s,n*sizeof(TYPE)); - } -} -// --------------------------------------------------------------------------- - -/* - * a key/value pair - */ - -template <typename KEY, typename VALUE> -struct key_value_pair_t { - KEY key; - VALUE value; - key_value_pair_t() { } - key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { } - key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { } - key_value_pair_t(const KEY& k) : key(k) { } - inline bool operator < (const key_value_pair_t& o) const { - return strictly_order_type(key, o.key); - } -}; - -template<> -template <typename K, typename V> -struct trait_trivial_ctor< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; }; -template<> -template <typename K, typename V> -struct trait_trivial_dtor< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; }; -template<> -template <typename K, typename V> -struct trait_trivial_copy< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; }; -template<> -template <typename K, typename V> -struct trait_trivial_assign< key_value_pair_t<K, V> > -{ enum { value = aggregate_traits<K,V>::has_trivial_assign};}; - -// --------------------------------------------------------------------------- - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_TYPE_HELPERS_H diff --git a/libpixelflinger/tinyutils/Vector.h b/libpixelflinger/tinyutils/Vector.h deleted file mode 100644 index 182bc7b5c2618a07d66abae03f77f2bfb935b0d6..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/Vector.h +++ /dev/null @@ -1,352 +0,0 @@ -/* - * vector.h - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_VECTOR_H -#define ANDROID_VECTOR_H - -#include <new> -#include <stdint.h> -#include <sys/types.h> - -#include <cutils/log.h> - -#include "tinyutils/VectorImpl.h" -#include "tinyutils/TypeHelpers.h" - -// --------------------------------------------------------------------------- - -namespace android { - -/*! - * The main templated vector class ensuring type safety - * while making use of VectorImpl. - * This is the class users want to use. - */ - -template <class TYPE> -class Vector : private VectorImpl -{ -public: - typedef TYPE value_type; - - /*! - * Constructors and destructors - */ - - Vector(); - Vector(const Vector<TYPE>& rhs); - virtual ~Vector(); - - /*! copy operator */ - const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const; - Vector<TYPE>& operator = (const Vector<TYPE>& rhs); - - /* - * empty the vector - */ - - inline void clear() { VectorImpl::clear(); } - - /*! - * vector stats - */ - - //! returns number of items in the vector - inline size_t size() const { return VectorImpl::size(); } - //! returns wether or not the vector is empty - inline bool isEmpty() const { return VectorImpl::isEmpty(); } - //! returns how many items can be stored without reallocating the backing store - inline size_t capacity() const { return VectorImpl::capacity(); } - //! setst the capacity. capacity can never be reduced less than size() - inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); } - - /*! - * C-style array access - */ - - //! read-only C-style access - inline const TYPE* array() const; - //! read-write C-style access - TYPE* editArray(); - - /*! - * accessors - */ - - //! read-only access to an item at a given index - inline const TYPE& operator [] (size_t index) const; - //! alternate name for operator [] - inline const TYPE& itemAt(size_t index) const; - //! stack-usage of the vector. returns the top of the stack (last element) - const TYPE& top() const; - //! same as operator [], but allows to access the vector backward (from the end) with a negative index - const TYPE& mirrorItemAt(ssize_t index) const; - - /*! - * modifing the array - */ - - //! copy-on write support, grants write access to an item - TYPE& editItemAt(size_t index); - //! grants right acces to the top of the stack (last element) - TYPE& editTop(); - - /*! - * append/insert another vector - */ - - //! insert another vector at a given index - ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index); - - //! append another vector at the end of this one - ssize_t appendVector(const Vector<TYPE>& vector); - - - /*! - * add/insert/replace items - */ - - //! insert one or several items initialized with their default constructor - inline ssize_t insertAt(size_t index, size_t numItems = 1); - //! insert on onr several items initialized from a prototype item - ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1); - //! pop the top of the stack (removes the last element). No-op if the stack's empty - inline void pop(); - //! pushes an item initialized with its default constructor - inline void push(); - //! pushes an item on the top of the stack - void push(const TYPE& item); - //! same as push() but returns the index the item was added at (or an error) - inline ssize_t add(); - //! same as push() but returns the index the item was added at (or an error) - ssize_t add(const TYPE& item); - //! replace an item with a new one initialized with its default constructor - inline ssize_t replaceAt(size_t index); - //! replace an item with a new one - ssize_t replaceAt(const TYPE& item, size_t index); - - /*! - * remove items - */ - - //! remove several items - inline ssize_t removeItemsAt(size_t index, size_t count = 1); - //! remove one item - inline ssize_t removeAt(size_t index) { return removeItemsAt(index); } - - /*! - * sort (stable) the array - */ - - typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs); - typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state); - - inline status_t sort(compar_t cmp); - inline status_t sort(compar_r_t cmp, void* state); - -protected: - virtual void do_construct(void* storage, size_t num) const; - virtual void do_destroy(void* storage, size_t num) const; - virtual void do_copy(void* dest, const void* from, size_t num) const; - virtual void do_splat(void* dest, const void* item, size_t num) const; - virtual void do_move_forward(void* dest, const void* from, size_t num) const; - virtual void do_move_backward(void* dest, const void* from, size_t num) const; -}; - - -// --------------------------------------------------------------------------- -// No user serviceable parts from here... -// --------------------------------------------------------------------------- - -template<class TYPE> inline -Vector<TYPE>::Vector() - : VectorImpl(sizeof(TYPE), - ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0) - |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0) - |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0) - |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0)) - ) -{ -} - -template<class TYPE> inline -Vector<TYPE>::Vector(const Vector<TYPE>& rhs) - : VectorImpl(rhs) { -} - -template<class TYPE> inline -Vector<TYPE>::~Vector() { - finish_vector(); -} - -template<class TYPE> inline -Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) { - VectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const { - VectorImpl::operator = (rhs); - return *this; -} - -template<class TYPE> inline -const TYPE* Vector<TYPE>::array() const { - return static_cast<const TYPE *>(arrayImpl()); -} - -template<class TYPE> inline -TYPE* Vector<TYPE>::editArray() { - return static_cast<TYPE *>(editArrayImpl()); -} - - -template<class TYPE> inline -const TYPE& Vector<TYPE>::operator[](size_t index) const { - LOG_FATAL_IF( index>=size(), - "itemAt: index %d is past size %d", (int)index, (int)size() ); - return *(array() + index); -} - -template<class TYPE> inline -const TYPE& Vector<TYPE>::itemAt(size_t index) const { - return operator[](index); -} - -template<class TYPE> inline -const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const { - LOG_FATAL_IF( (index>0 ? index : -index)>=size(), - "mirrorItemAt: index %d is past size %d", - (int)index, (int)size() ); - return *(array() + ((index<0) ? (size()-index) : index)); -} - -template<class TYPE> inline -const TYPE& Vector<TYPE>::top() const { - return *(array() + size() - 1); -} - -template<class TYPE> inline -TYPE& Vector<TYPE>::editItemAt(size_t index) { - return *( static_cast<TYPE *>(editItemLocation(index)) ); -} - -template<class TYPE> inline -TYPE& Vector<TYPE>::editTop() { - return *( static_cast<TYPE *>(editItemLocation(size()-1)) ); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) { - return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) { - return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector)); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) { - return VectorImpl::insertAt(&item, index, numItems); -} - -template<class TYPE> inline -void Vector<TYPE>::push(const TYPE& item) { - return VectorImpl::push(&item); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::add(const TYPE& item) { - return VectorImpl::add(&item); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) { - return VectorImpl::replaceAt(&item, index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) { - return VectorImpl::insertAt(index, numItems); -} - -template<class TYPE> inline -void Vector<TYPE>::pop() { - VectorImpl::pop(); -} - -template<class TYPE> inline -void Vector<TYPE>::push() { - VectorImpl::push(); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::add() { - return VectorImpl::add(); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::replaceAt(size_t index) { - return VectorImpl::replaceAt(index); -} - -template<class TYPE> inline -ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) { - return VectorImpl::removeItemsAt(index, count); -} - -template<class TYPE> inline -status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) { - return VectorImpl::sort((VectorImpl::compar_t)cmp); -} - -template<class TYPE> inline -status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) { - return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state); -} - -// --------------------------------------------------------------------------- - -template<class TYPE> -void Vector<TYPE>::do_construct(void* storage, size_t num) const { - construct_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_destroy(void* storage, size_t num) const { - destroy_type( reinterpret_cast<TYPE*>(storage), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const { - copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const { - splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const { - move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -template<class TYPE> -void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const { - move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num ); -} - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_H diff --git a/libpixelflinger/tinyutils/VectorImpl.cpp b/libpixelflinger/tinyutils/VectorImpl.cpp deleted file mode 100644 index a0497064251f543d83d5a29c05215d1c897f4833..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/VectorImpl.cpp +++ /dev/null @@ -1,552 +0,0 @@ -/* - * vector_impl.cpp - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#define LOG_TAG "Vector" - -#include <string.h> -#include <stdlib.h> -#include <stdio.h> -#include <errno.h> - -#include <cutils/log.h> - -#include "tinyutils/SharedBuffer.h" -#include "tinyutils/VectorImpl.h" - -/*****************************************************************************/ - - -namespace android { - -enum { - NO_ERROR = 0, // No errors. - NO_MEMORY = -ENOMEM, - BAD_VALUE = -EINVAL, - BAD_INDEX = -EOVERFLOW, - NAME_NOT_FOUND = -ENOENT, -}; - -// ---------------------------------------------------------------------------- - -const size_t kMinVectorCapacity = 4; - -static inline size_t max(size_t a, size_t b) { - return a>b ? a : b; -} - -// ---------------------------------------------------------------------------- - -VectorImpl::VectorImpl(size_t itemSize, uint32_t flags) - : mStorage(0), mCount(0), mFlags(flags), mItemSize(itemSize) -{ -} - -VectorImpl::VectorImpl(const VectorImpl& rhs) - : mStorage(rhs.mStorage), mCount(rhs.mCount), - mFlags(rhs.mFlags), mItemSize(rhs.mItemSize) -{ - if (mStorage) { - SharedBuffer::sharedBuffer(mStorage)->acquire(); - } -} - -VectorImpl::~VectorImpl() -{ - LOG_ASSERT(!mCount, - "[%p] " - "subclasses of VectorImpl must call finish_vector()" - " in their destructor. Leaking %d bytes.", - this, (int)(mCount*mItemSize)); - // We can't call _do_destroy() here because the vtable is already gone. -} - -VectorImpl& VectorImpl::operator = (const VectorImpl& rhs) -{ - LOG_ASSERT(mItemSize == rhs.mItemSize, - "Vector<> have different types (this=%p, rhs=%p)", this, &rhs); - if (this != &rhs) { - release_storage(); - if (rhs.mCount) { - mStorage = rhs.mStorage; - mCount = rhs.mCount; - SharedBuffer::sharedBuffer(mStorage)->acquire(); - } else { - mStorage = 0; - mCount = 0; - } - } - return *this; -} - -void* VectorImpl::editArrayImpl() -{ - if (mStorage) { - SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage)->attemptEdit(); - if (sb == 0) { - sb = SharedBuffer::alloc(capacity() * mItemSize); - if (sb) { - _do_copy(sb->data(), mStorage, mCount); - release_storage(); - mStorage = sb->data(); - } - } - } - return mStorage; -} - -size_t VectorImpl::capacity() const -{ - if (mStorage) { - return SharedBuffer::sharedBuffer(mStorage)->size() / mItemSize; - } - return 0; -} - -ssize_t VectorImpl::insertVectorAt(const VectorImpl& vector, size_t index) -{ - if (index > size()) - return BAD_INDEX; - void* where = _grow(index, vector.size()); - if (where) { - _do_copy(where, vector.arrayImpl(), vector.size()); - } - return where ? index : (ssize_t)NO_MEMORY; -} - -ssize_t VectorImpl::appendVector(const VectorImpl& vector) -{ - return insertVectorAt(vector, size()); -} - -ssize_t VectorImpl::insertAt(size_t index, size_t numItems) -{ - return insertAt(0, index, numItems); -} - -ssize_t VectorImpl::insertAt(const void* item, size_t index, size_t numItems) -{ - if (index > size()) - return BAD_INDEX; - void* where = _grow(index, numItems); - if (where) { - if (item) { - _do_splat(where, item, numItems); - } else { - _do_construct(where, numItems); - } - } - return where ? index : (ssize_t)NO_MEMORY; -} - -void VectorImpl::pop() -{ - if (size()) - removeItemsAt(size()-1, 1); -} - -void VectorImpl::push() -{ - push(0); -} - -void VectorImpl::push(const void* item) -{ - insertAt(item, size()); -} - -ssize_t VectorImpl::add() -{ - return add(0); -} - -ssize_t VectorImpl::add(const void* item) -{ - return insertAt(item, size()); -} - -ssize_t VectorImpl::replaceAt(size_t index) -{ - return replaceAt(0, index); -} - -ssize_t VectorImpl::replaceAt(const void* prototype, size_t index) -{ - LOG_ASSERT(index<size(), - "[%p] replace: index=%d, size=%d", this, (int)index, (int)size()); - - void* item = editItemLocation(index); - if (item == 0) - return NO_MEMORY; - _do_destroy(item, 1); - if (prototype == 0) { - _do_construct(item, 1); - } else { - _do_copy(item, prototype, 1); - } - return ssize_t(index); -} - -ssize_t VectorImpl::removeItemsAt(size_t index, size_t count) -{ - LOG_ASSERT((index+count)<=size(), - "[%p] remove: index=%d, count=%d, size=%d", - this, (int)index, (int)count, (int)size()); - - if ((index+count) > size()) - return BAD_VALUE; - _shrink(index, count); - return index; -} - -void VectorImpl::finish_vector() -{ - release_storage(); - mStorage = 0; - mCount = 0; -} - -void VectorImpl::clear() -{ - _shrink(0, mCount); -} - -void* VectorImpl::editItemLocation(size_t index) -{ - LOG_ASSERT(index<capacity(), - "[%p] itemLocation: index=%d, capacity=%d, count=%d", - this, (int)index, (int)capacity(), (int)mCount); - - void* buffer = editArrayImpl(); - if (buffer) - return reinterpret_cast<char*>(buffer) + index*mItemSize; - return 0; -} - -const void* VectorImpl::itemLocation(size_t index) const -{ - LOG_ASSERT(index<capacity(), - "[%p] editItemLocation: index=%d, capacity=%d, count=%d", - this, (int)index, (int)capacity(), (int)mCount); - - const void* buffer = arrayImpl(); - if (buffer) - return reinterpret_cast<const char*>(buffer) + index*mItemSize; - return 0; -} - -ssize_t VectorImpl::setCapacity(size_t new_capacity) -{ - size_t current_capacity = capacity(); - ssize_t amount = new_capacity - size(); - if (amount <= 0) { - // we can't reduce the capacity - return current_capacity; - } - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - _do_copy(array, mStorage, size()); - release_storage(); - mStorage = const_cast<void*>(array); - } else { - return NO_MEMORY; - } - return new_capacity; -} - -void VectorImpl::release_storage() -{ - if (mStorage) { - const SharedBuffer* sb = SharedBuffer::sharedBuffer(mStorage); - if (sb->release(SharedBuffer::eKeepStorage) == 1) { - _do_destroy(mStorage, mCount); - SharedBuffer::dealloc(sb); - } - } -} - -void* VectorImpl::_grow(size_t where, size_t amount) -{ -// LOGV("_grow(this=%p, where=%d, amount=%d) count=%d, capacity=%d", -// this, (int)where, (int)amount, (int)mCount, (int)capacity()); - - if (where > mCount) - where = mCount; - - const size_t new_size = mCount + amount; - if (capacity() < new_size) { - const size_t new_capacity = max(kMinVectorCapacity, ((new_size*3)+1)/2); -// LOGV("grow vector %p, new_capacity=%d", this, (int)new_capacity); - if ((mStorage) && - (mCount==where) && - (mFlags & HAS_TRIVIAL_COPY) && - (mFlags & HAS_TRIVIAL_DTOR)) - { - const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage); - SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); - mStorage = sb->data(); - } else { - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - if (where>0) { - _do_copy(array, mStorage, where); - } - if (mCount>where) { - const void* from = reinterpret_cast<const uint8_t *>(mStorage) + where*mItemSize; - void* dest = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - _do_copy(dest, from, mCount-where); - } - release_storage(); - mStorage = const_cast<void*>(array); - } - } - } else { - ssize_t s = mCount-where; - if (s>0) { - void* array = editArrayImpl(); - void* to = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - const void* from = reinterpret_cast<const uint8_t *>(array) + where*mItemSize; - _do_move_forward(to, from, s); - } - } - mCount += amount; - void* free_space = const_cast<void*>(itemLocation(where)); - return free_space; -} - -void VectorImpl::_shrink(size_t where, size_t amount) -{ - if (!mStorage) - return; - -// LOGV("_shrink(this=%p, where=%d, amount=%d) count=%d, capacity=%d", -// this, (int)where, (int)amount, (int)mCount, (int)capacity()); - - if (where >= mCount) - where = mCount - amount; - - const size_t new_size = mCount - amount; - if (new_size*3 < capacity()) { - const size_t new_capacity = max(kMinVectorCapacity, new_size*2); -// LOGV("shrink vector %p, new_capacity=%d", this, (int)new_capacity); - if ((where == mCount-amount) && - (mFlags & HAS_TRIVIAL_COPY) && - (mFlags & HAS_TRIVIAL_DTOR)) - { - const SharedBuffer* cur_sb = SharedBuffer::sharedBuffer(mStorage); - SharedBuffer* sb = cur_sb->editResize(new_capacity * mItemSize); - mStorage = sb->data(); - } else { - SharedBuffer* sb = SharedBuffer::alloc(new_capacity * mItemSize); - if (sb) { - void* array = sb->data(); - if (where>0) { - _do_copy(array, mStorage, where); - } - if (mCount > where+amount) { - const void* from = reinterpret_cast<const uint8_t *>(mStorage) + (where+amount)*mItemSize; - void* dest = reinterpret_cast<uint8_t *>(array) + where*mItemSize; - _do_copy(dest, from, mCount-(where+amount)); - } - release_storage(); - mStorage = const_cast<void*>(array); - } - } - } else { - void* array = editArrayImpl(); - void* to = reinterpret_cast<uint8_t *>(array) + where*mItemSize; - _do_destroy(to, amount); - ssize_t s = mCount-(where+amount); - if (s>0) { - const void* from = reinterpret_cast<uint8_t *>(array) + (where+amount)*mItemSize; - _do_move_backward(to, from, s); - } - } - - // adjust the number of items... - mCount -= amount; -} - -size_t VectorImpl::itemSize() const { - return mItemSize; -} - -void VectorImpl::_do_construct(void* storage, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_CTOR)) { - do_construct(storage, num); - } -} - -void VectorImpl::_do_destroy(void* storage, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_DTOR)) { - do_destroy(storage, num); - } -} - -void VectorImpl::_do_copy(void* dest, const void* from, size_t num) const -{ - if (!(mFlags & HAS_TRIVIAL_COPY)) { - do_copy(dest, from, num); - } else { - memcpy(dest, from, num*itemSize()); - } -} - -void VectorImpl::_do_splat(void* dest, const void* item, size_t num) const { - do_splat(dest, item, num); -} - -void VectorImpl::_do_move_forward(void* dest, const void* from, size_t num) const { - do_move_forward(dest, from, num); -} - -void VectorImpl::_do_move_backward(void* dest, const void* from, size_t num) const { - do_move_backward(dest, from, num); -} - -void VectorImpl::reservedVectorImpl1() { } -void VectorImpl::reservedVectorImpl2() { } -void VectorImpl::reservedVectorImpl3() { } -void VectorImpl::reservedVectorImpl4() { } -void VectorImpl::reservedVectorImpl5() { } -void VectorImpl::reservedVectorImpl6() { } -void VectorImpl::reservedVectorImpl7() { } -void VectorImpl::reservedVectorImpl8() { } - -/*****************************************************************************/ - -SortedVectorImpl::SortedVectorImpl(size_t itemSize, uint32_t flags) - : VectorImpl(itemSize, flags) -{ -} - -SortedVectorImpl::SortedVectorImpl(const VectorImpl& rhs) -: VectorImpl(rhs) -{ -} - -SortedVectorImpl::~SortedVectorImpl() -{ -} - -SortedVectorImpl& SortedVectorImpl::operator = (const SortedVectorImpl& rhs) -{ - return static_cast<SortedVectorImpl&>( VectorImpl::operator = (static_cast<const VectorImpl&>(rhs)) ); -} - -ssize_t SortedVectorImpl::indexOf(const void* item) const -{ - return _indexOrderOf(item); -} - -size_t SortedVectorImpl::orderOf(const void* item) const -{ - size_t o; - _indexOrderOf(item, &o); - return o; -} - -ssize_t SortedVectorImpl::_indexOrderOf(const void* item, size_t* order) const -{ - // binary search - ssize_t err = NAME_NOT_FOUND; - ssize_t l = 0; - ssize_t h = size()-1; - ssize_t mid; - const void* a = arrayImpl(); - const size_t s = itemSize(); - while (l <= h) { - mid = l + (h - l)/2; - const void* const curr = reinterpret_cast<const char *>(a) + (mid*s); - const int c = do_compare(curr, item); - if (c == 0) { - err = l = mid; - break; - } else if (c < 0) { - l = mid + 1; - } else { - h = mid - 1; - } - } - if (order) *order = l; - return err; -} - -ssize_t SortedVectorImpl::add(const void* item) -{ - size_t order; - ssize_t index = _indexOrderOf(item, &order); - if (index < 0) { - index = VectorImpl::insertAt(item, order, 1); - } else { - index = VectorImpl::replaceAt(item, index); - } - return index; -} - -ssize_t SortedVectorImpl::merge(const VectorImpl& vector) -{ - // naive merge... - if (!vector.isEmpty()) { - const void* buffer = vector.arrayImpl(); - const size_t is = itemSize(); - size_t s = vector.size(); - for (size_t i=0 ; i<s ; i++) { - ssize_t err = add( reinterpret_cast<const char*>(buffer) + i*is ); - if (err<0) { - return err; - } - } - } - return NO_ERROR; -} - -ssize_t SortedVectorImpl::merge(const SortedVectorImpl& vector) -{ - // we've merging a sorted vector... nice! - ssize_t err = NO_ERROR; - if (!vector.isEmpty()) { - // first take care of the case where the vectors are sorted together - if (do_compare(vector.itemLocation(vector.size()-1), arrayImpl()) <= 0) { - err = VectorImpl::insertVectorAt(static_cast<const VectorImpl&>(vector), 0); - } else if (do_compare(vector.arrayImpl(), itemLocation(size()-1)) >= 0) { - err = VectorImpl::appendVector(static_cast<const VectorImpl&>(vector)); - } else { - // this could be made a little better - err = merge(static_cast<const VectorImpl&>(vector)); - } - } - return err; -} - -ssize_t SortedVectorImpl::remove(const void* item) -{ - ssize_t i = indexOf(item); - if (i>=0) { - VectorImpl::removeItemsAt(i, 1); - } - return i; -} - -void SortedVectorImpl::reservedSortedVectorImpl1() { }; -void SortedVectorImpl::reservedSortedVectorImpl2() { }; -void SortedVectorImpl::reservedSortedVectorImpl3() { }; -void SortedVectorImpl::reservedSortedVectorImpl4() { }; -void SortedVectorImpl::reservedSortedVectorImpl5() { }; -void SortedVectorImpl::reservedSortedVectorImpl6() { }; -void SortedVectorImpl::reservedSortedVectorImpl7() { }; -void SortedVectorImpl::reservedSortedVectorImpl8() { }; - - -/*****************************************************************************/ - -}; // namespace android - diff --git a/libpixelflinger/tinyutils/VectorImpl.h b/libpixelflinger/tinyutils/VectorImpl.h deleted file mode 100644 index e868ecaf95f9fd3d69b540adad879f4f05582f28..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/VectorImpl.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * vector_impl.h - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_VECTOR_IMPL_H -#define ANDROID_VECTOR_IMPL_H - -#include <assert.h> -#include <stdint.h> -#include <sys/types.h> - -// --------------------------------------------------------------------------- -// No user serviceable parts in here... -// --------------------------------------------------------------------------- - -namespace android { - -/*! - * Implementation of the guts of the vector<> class - * this ensures backward binary compatibility and - * reduces code size. - * For performance reasons, we expose mStorage and mCount - * so these fields are set in stone. - * - */ - -class VectorImpl -{ -public: - enum { // flags passed to the ctor - HAS_TRIVIAL_CTOR = 0x00000001, - HAS_TRIVIAL_DTOR = 0x00000002, - HAS_TRIVIAL_COPY = 0x00000004, - HAS_TRIVIAL_ASSIGN = 0x00000008 - }; - - VectorImpl(size_t itemSize, uint32_t flags); - VectorImpl(const VectorImpl& rhs); - virtual ~VectorImpl(); - - /*! must be called from subclasses destructor */ - void finish_vector(); - - VectorImpl& operator = (const VectorImpl& rhs); - - /*! C-style array access */ - inline const void* arrayImpl() const { return mStorage; } - void* editArrayImpl(); - - /*! vector stats */ - inline size_t size() const { return mCount; } - inline bool isEmpty() const { return mCount == 0; } - size_t capacity() const; - ssize_t setCapacity(size_t size); - - /*! append/insert another vector */ - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - - /*! add/insert/replace items */ - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - void pop(); - void push(); - void push(const void* item); - ssize_t add(); - ssize_t add(const void* item); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); - - /*! remove items */ - ssize_t removeItemsAt(size_t index, size_t count = 1); - void clear(); - - const void* itemLocation(size_t index) const; - void* editItemLocation(size_t index); - -protected: - size_t itemSize() const; - void release_storage(); - - virtual void do_construct(void* storage, size_t num) const = 0; - virtual void do_destroy(void* storage, size_t num) const = 0; - virtual void do_copy(void* dest, const void* from, size_t num) const = 0; - virtual void do_splat(void* dest, const void* item, size_t num) const = 0; - virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0; - virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0; - - // take care of FBC... - virtual void reservedVectorImpl1(); - virtual void reservedVectorImpl2(); - virtual void reservedVectorImpl3(); - virtual void reservedVectorImpl4(); - virtual void reservedVectorImpl5(); - virtual void reservedVectorImpl6(); - virtual void reservedVectorImpl7(); - virtual void reservedVectorImpl8(); - -private: - void* _grow(size_t where, size_t amount); - void _shrink(size_t where, size_t amount); - - inline void _do_construct(void* storage, size_t num) const; - inline void _do_destroy(void* storage, size_t num) const; - inline void _do_copy(void* dest, const void* from, size_t num) const; - inline void _do_splat(void* dest, const void* item, size_t num) const; - inline void _do_move_forward(void* dest, const void* from, size_t num) const; - inline void _do_move_backward(void* dest, const void* from, size_t num) const; - - // These 2 fields are exposed in the inlines below, - // so they're set in stone. - void * mStorage; // base address of the vector - size_t mCount; // number of items - - const uint32_t mFlags; - const size_t mItemSize; -}; - - - -class SortedVectorImpl : public VectorImpl -{ -public: - SortedVectorImpl(size_t itemSize, uint32_t flags); - SortedVectorImpl(const VectorImpl& rhs); - virtual ~SortedVectorImpl(); - - SortedVectorImpl& operator = (const SortedVectorImpl& rhs); - - //! finds the index of an item - ssize_t indexOf(const void* item) const; - - //! finds where this item should be inserted - size_t orderOf(const void* item) const; - - //! add an item in the right place (or replaces it if there is one) - ssize_t add(const void* item); - - //! merges a vector into this one - ssize_t merge(const VectorImpl& vector); - ssize_t merge(const SortedVectorImpl& vector); - - //! removes an item - ssize_t remove(const void* item); - -protected: - virtual int do_compare(const void* lhs, const void* rhs) const = 0; - - // take care of FBC... - virtual void reservedSortedVectorImpl1(); - virtual void reservedSortedVectorImpl2(); - virtual void reservedSortedVectorImpl3(); - virtual void reservedSortedVectorImpl4(); - virtual void reservedSortedVectorImpl5(); - virtual void reservedSortedVectorImpl6(); - virtual void reservedSortedVectorImpl7(); - virtual void reservedSortedVectorImpl8(); - -private: - ssize_t _indexOrderOf(const void* item, size_t* order = 0) const; - - // these are made private, because they can't be used on a SortedVector - // (they don't have an implementation either) - ssize_t add(); - void pop(); - void push(); - void push(const void* item); - ssize_t insertVectorAt(const VectorImpl& vector, size_t index); - ssize_t appendVector(const VectorImpl& vector); - ssize_t insertAt(size_t where, size_t numItems = 1); - ssize_t insertAt(const void* item, size_t where, size_t numItems = 1); - ssize_t replaceAt(size_t index); - ssize_t replaceAt(const void* item, size_t index); -}; - -}; // namespace android - - -// --------------------------------------------------------------------------- - -#endif // ANDROID_VECTOR_IMPL_H diff --git a/libpixelflinger/tinyutils/smartpointer.h b/libpixelflinger/tinyutils/smartpointer.h deleted file mode 100644 index 88032d7fbcdab634c4f7371ebef435acfca6882e..0000000000000000000000000000000000000000 --- a/libpixelflinger/tinyutils/smartpointer.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * smartpointer.h - * Android - * - * Copyright 2005 The Android Open Source Project - * - */ - -#ifndef ANDROID_SMART_POINTER_H -#define ANDROID_SMART_POINTER_H - -#include <stdint.h> -#include <sys/types.h> -#include <stdlib.h> - -// --------------------------------------------------------------------------- -namespace android { - -// --------------------------------------------------------------------------- - -#define COMPARE(_op_) \ -inline bool operator _op_ (const sp<T>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -inline bool operator _op_ (const T* o) const { \ - return m_ptr _op_ o; \ -} \ -template<typename U> \ -inline bool operator _op_ (const sp<U>& o) const { \ - return m_ptr _op_ o.m_ptr; \ -} \ -template<typename U> \ -inline bool operator _op_ (const U* o) const { \ - return m_ptr _op_ o; \ -} - -// --------------------------------------------------------------------------- - -template <typename T> -class sp -{ -public: - inline sp() : m_ptr(0) { } - - sp(T* other); - sp(const sp<T>& other); - template<typename U> sp(U* other); - template<typename U> sp(const sp<U>& other); - - ~sp(); - - // Assignment - - sp& operator = (T* other); - sp& operator = (const sp<T>& other); - - template<typename U> sp& operator = (const sp<U>& other); - template<typename U> sp& operator = (U* other); - - // Reset - void clear(); - - // Accessors - - inline T& operator* () const { return *m_ptr; } - inline T* operator-> () const { return m_ptr; } - inline T* get() const { return m_ptr; } - - // Operators - - COMPARE(==) - COMPARE(!=) - COMPARE(>) - COMPARE(<) - COMPARE(<=) - COMPARE(>=) - -private: - template<typename Y> friend class sp; - - T* m_ptr; -}; - -// --------------------------------------------------------------------------- -// No user serviceable parts below here. - -template<typename T> -sp<T>::sp(T* other) - : m_ptr(other) -{ - if (other) other->incStrong(this); -} - -template<typename T> -sp<T>::sp(const sp<T>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) m_ptr->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(U* other) : m_ptr(other) -{ - if (other) other->incStrong(this); -} - -template<typename T> template<typename U> -sp<T>::sp(const sp<U>& other) - : m_ptr(other.m_ptr) -{ - if (m_ptr) m_ptr->incStrong(this); -} - -template<typename T> -sp<T>::~sp() -{ - if (m_ptr) m_ptr->decStrong(this); -} - -template<typename T> -sp<T>& sp<T>::operator = (const sp<T>& other) { - if (other.m_ptr) other.m_ptr->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other.m_ptr; - return *this; -} - -template<typename T> -sp<T>& sp<T>::operator = (T* other) -{ - if (other) other->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator = (const sp<U>& other) -{ - if (other.m_ptr) other.m_ptr->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other.m_ptr; - return *this; -} - -template<typename T> template<typename U> -sp<T>& sp<T>::operator = (U* other) -{ - if (other) other->incStrong(this); - if (m_ptr) m_ptr->decStrong(this); - m_ptr = other; - return *this; -} - -template<typename T> -void sp<T>::clear() -{ - if (m_ptr) { - m_ptr->decStrong(this); - m_ptr = 0; - } -} - -// --------------------------------------------------------------------------- - -}; // namespace android - -// --------------------------------------------------------------------------- - -#endif // ANDROID_SMART_POINTER_H diff --git a/libpixelflinger/trap.cpp b/libpixelflinger/trap.cpp deleted file mode 100644 index 30b633f1bd9dbd6b9507c360740c22c07bbe3c2e..0000000000000000000000000000000000000000 --- a/libpixelflinger/trap.cpp +++ /dev/null @@ -1,1173 +0,0 @@ -/* libs/pixelflinger/trap.cpp -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <assert.h> -#include <stdio.h> -#include <stdlib.h> - -#include "trap.h" -#include "picker.h" - -#include <cutils/log.h> -#include <cutils/memory.h> - -namespace android { - -// ---------------------------------------------------------------------------- - -// enable to see triangles edges -#define DEBUG_TRANGLES 0 - -// ---------------------------------------------------------------------------- - -static void pointx_validate(void *con, const GGLcoord* c, GGLcoord r); -static void pointx(void *con, const GGLcoord* c, GGLcoord r); -static void aa_pointx(void *con, const GGLcoord* c, GGLcoord r); -static void aa_nice_pointx(void *con, const GGLcoord* c, GGLcoord r); - -static void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w); -static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w); -static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w); - -static void recti_validate(void* c, GGLint l, GGLint t, GGLint r, GGLint b); -static void recti(void* c, GGLint l, GGLint t, GGLint r, GGLint b); - -static void trianglex_validate(void*, - const GGLcoord*, const GGLcoord*, const GGLcoord*); -static void trianglex_small(void*, - const GGLcoord*, const GGLcoord*, const GGLcoord*); -static void trianglex_big(void*, - const GGLcoord*, const GGLcoord*, const GGLcoord*); -static void aa_trianglex(void*, - const GGLcoord*, const GGLcoord*, const GGLcoord*); -static void trianglex_debug(void* con, - const GGLcoord*, const GGLcoord*, const GGLcoord*); - -static void aapolyx(void* con, - const GGLcoord* pts, int count); - -static inline int min(int a, int b) CONST; -static inline int max(int a, int b) CONST; -static inline int min(int a, int b, int c) CONST; -static inline int max(int a, int b, int c) CONST; - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Tools -#endif - -inline int min(int a, int b) { - return a<b ? a : b; -} -inline int max(int a, int b) { - return a<b ? b : a; -} -inline int min(int a, int b, int c) { - return min(a,min(b,c)); -} -inline int max(int a, int b, int c) { - return max(a,max(b,c)); -} - -template <typename T> -static inline void swap(T& a, T& b) { - T t(a); - a = b; - b = t; -} - -static void -triangle_dump_points( const GGLcoord* v0, - const GGLcoord* v1, - const GGLcoord* v2 ) -{ - float tri = 1.0f / TRI_ONE; - LOGD( " P0=(%.3f, %.3f) [%08x, %08x]\n" - " P1=(%.3f, %.3f) [%08x, %08x]\n" - " P2=(%.3f, %.3f) [%08x, %08x]\n", - v0[0]*tri, v0[1]*tri, v0[0], v0[1], - v1[0]*tri, v1[1]*tri, v1[0], v1[1], - v2[0]*tri, v2[1]*tri, v2[0], v2[1] ); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Misc -#endif - -void ggl_init_trap(context_t* c) -{ - ggl_state_changed(c, GGL_PIXEL_PIPELINE_STATE|GGL_TMU_STATE|GGL_CB_STATE); -} - -void ggl_state_changed(context_t* c, int flags) -{ - if (ggl_likely(!c->dirty)) { - c->procs.pointx = pointx_validate; - c->procs.linex = linex_validate; - c->procs.recti = recti_validate; - c->procs.trianglex = trianglex_validate; - } - c->dirty |= uint32_t(flags); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Point -#endif - -void pointx_validate(void *con, const GGLcoord* v, GGLcoord rad) -{ - GGL_CONTEXT(c, con); - ggl_pick(c); - if (c->state.needs.p & GGL_NEED_MASK(P_AA)) { - if (c->state.enables & GGL_ENABLE_POINT_AA_NICE) { - c->procs.pointx = aa_nice_pointx; - } else { - c->procs.pointx = aa_pointx; - } - } else { - c->procs.pointx = pointx; - } - c->procs.pointx(con, v, rad); -} - -void pointx(void *con, const GGLcoord* v, GGLcoord rad) -{ - GGL_CONTEXT(c, con); - GGLcoord halfSize = TRI_ROUND(rad) >> 1; - if (halfSize == 0) - halfSize = TRI_HALF; - GGLcoord xc = v[0]; - GGLcoord yc = v[1]; - if (halfSize & TRI_HALF) { // size odd - xc = TRI_FLOOR(xc) + TRI_HALF; - yc = TRI_FLOOR(yc) + TRI_HALF; - } else { // size even - xc = TRI_ROUND(xc); - yc = TRI_ROUND(yc); - } - GGLint l = (xc - halfSize) >> TRI_FRACTION_BITS; - GGLint t = (yc - halfSize) >> TRI_FRACTION_BITS; - GGLint r = (xc + halfSize) >> TRI_FRACTION_BITS; - GGLint b = (yc + halfSize) >> TRI_FRACTION_BITS; - recti(c, l, t, r, b); -} - -// This way of computing the coverage factor, is more accurate and gives -// better results for small circles, but it is also a lot slower. -// Here we use super-sampling. -static int32_t coverageNice(GGLcoord x, GGLcoord y, - GGLcoord rmin, GGLcoord rmax, GGLcoord rr) -{ - const GGLcoord d2 = x*x + y*y; - if (d2 >= rmax) return 0; - if (d2 < rmin) return 0x7FFF; - - const int kSamples = 4; - const int kInc = 4; // 1/4 = 0.25 - const int kCoverageUnit = 1; // 1/(4^2) = 0.0625 - const GGLcoord kCoordOffset = -6; // -0.375 - - int hits = 0; - int x_sample = x + kCoordOffset; - for (int i=0 ; i<kSamples ; i++, x_sample += kInc) { - const int xval = rr - (x_sample * x_sample); - int y_sample = y + kCoordOffset; - for (int j=0 ; j<kSamples ; j++, y_sample += kInc) { - if (xval - (y_sample * y_sample) > 0) - hits += kCoverageUnit; - } - } - return min(0x7FFF, hits << (15 - kSamples)); -} - - -void aa_nice_pointx(void *con, const GGLcoord* v, GGLcoord size) -{ - GGL_CONTEXT(c, con); - - GGLcoord rad = ((size + 1)>>1); - GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS; - GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS; - GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS; - GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS; - GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF; - GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF; - - // scissor... - if (l < GGLint(c->state.scissor.left)) { - xstart += TRI_FROM_INT(c->state.scissor.left-l); - l = GGLint(c->state.scissor.left); - } - if (t < GGLint(c->state.scissor.top)) { - ystart += TRI_FROM_INT(c->state.scissor.top-t); - t = GGLint(c->state.scissor.top); - } - if (r > GGLint(c->state.scissor.right)) { - r = GGLint(c->state.scissor.right); - } - if (b > GGLint(c->state.scissor.bottom)) { - b = GGLint(c->state.scissor.bottom); - } - - int xc = r - l; - int yc = b - t; - if (xc>0 && yc>0) { - int16_t* covPtr = c->state.buffers.coverage; - const int32_t sqr2Over2 = 0xC; // rounded up - GGLcoord rr = rad*rad; - GGLcoord rmin = (rad - sqr2Over2)*(rad - sqr2Over2); - GGLcoord rmax = (rad + sqr2Over2)*(rad + sqr2Over2); - GGLcoord y = ystart; - c->iterators.xl = l; - c->iterators.xr = r; - c->init_y(c, t); - do { - // compute coverage factors for each pixel - GGLcoord x = xstart; - for (int i=l ; i<r ; i++) { - covPtr[i] = coverageNice(x, y, rmin, rmax, rr); - x += TRI_ONE; - } - y += TRI_ONE; - c->scanline(c); - c->step_y(c); - } while (--yc); - } -} - -// This is a cheap way of computing the coverage factor for a circle. -// We just lerp between the circles of radii r-sqrt(2)/2 and r+sqrt(2)/2 -static inline int32_t coverageFast(GGLcoord x, GGLcoord y, - GGLcoord rmin, GGLcoord rmax, GGLcoord scale) -{ - const GGLcoord d2 = x*x + y*y; - if (d2 >= rmax) return 0; - if (d2 < rmin) return 0x7FFF; - return 0x7FFF - (d2-rmin)*scale; -} - -void aa_pointx(void *con, const GGLcoord* v, GGLcoord size) -{ - GGL_CONTEXT(c, con); - - GGLcoord rad = ((size + 1)>>1); - GGLint l = (v[0] - rad) >> TRI_FRACTION_BITS; - GGLint t = (v[1] - rad) >> TRI_FRACTION_BITS; - GGLint r = (v[0] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS; - GGLint b = (v[1] + rad + (TRI_ONE-1)) >> TRI_FRACTION_BITS; - GGLcoord xstart = TRI_FROM_INT(l) - v[0] + TRI_HALF; - GGLcoord ystart = TRI_FROM_INT(t) - v[1] + TRI_HALF; - - // scissor... - if (l < GGLint(c->state.scissor.left)) { - xstart += TRI_FROM_INT(c->state.scissor.left-l); - l = GGLint(c->state.scissor.left); - } - if (t < GGLint(c->state.scissor.top)) { - ystart += TRI_FROM_INT(c->state.scissor.top-t); - t = GGLint(c->state.scissor.top); - } - if (r > GGLint(c->state.scissor.right)) { - r = GGLint(c->state.scissor.right); - } - if (b > GGLint(c->state.scissor.bottom)) { - b = GGLint(c->state.scissor.bottom); - } - - int xc = r - l; - int yc = b - t; - if (xc>0 && yc>0) { - int16_t* covPtr = c->state.buffers.coverage; - rad <<= 4; - const int32_t sqr2Over2 = 0xB5; // fixed-point 24.8 - GGLcoord rmin = rad - sqr2Over2; - GGLcoord rmax = rad + sqr2Over2; - GGLcoord scale; - rmin *= rmin; - rmax *= rmax; - scale = 0x800000 / (rmax - rmin); - rmin >>= 8; - rmax >>= 8; - - GGLcoord y = ystart; - c->iterators.xl = l; - c->iterators.xr = r; - c->init_y(c, t); - - do { - // compute coverage factors for each pixel - GGLcoord x = xstart; - for (int i=l ; i<r ; i++) { - covPtr[i] = coverageFast(x, y, rmin, rmax, scale); - x += TRI_ONE; - } - y += TRI_ONE; - c->scanline(c); - c->step_y(c); - } while (--yc); - } -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Line -#endif - -void linex_validate(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord w) -{ - GGL_CONTEXT(c, con); - ggl_pick(c); - if (c->state.needs.p & GGL_NEED_MASK(P_AA)) { - c->procs.linex = aa_linex; - } else { - c->procs.linex = linex; - } - c->procs.linex(con, v0, v1, w); -} - -static void linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width) -{ - GGL_CONTEXT(c, con); - GGLcoord v[4][2]; - v[0][0] = v0[0]; v[0][1] = v0[1]; - v[1][0] = v1[0]; v[1][1] = v1[1]; - v0 = v[0]; - v1 = v[1]; - const GGLcoord dx = abs(v0[0] - v1[0]); - const GGLcoord dy = abs(v0[1] - v1[1]); - GGLcoord nx, ny; - nx = ny = 0; - - GGLcoord halfWidth = TRI_ROUND(width) >> 1; - if (halfWidth == 0) - halfWidth = TRI_HALF; - - ((dx > dy) ? ny : nx) = halfWidth; - v[2][0] = v1[0]; v[2][1] = v1[1]; - v[3][0] = v0[0]; v[3][1] = v0[1]; - v[0][0] += nx; v[0][1] += ny; - v[1][0] += nx; v[1][1] += ny; - v[2][0] -= nx; v[2][1] -= ny; - v[3][0] -= nx; v[3][1] -= ny; - trianglex_big(con, v[0], v[1], v[2]); - trianglex_big(con, v[0], v[2], v[3]); -} - -static void aa_linex(void *con, const GGLcoord* v0, const GGLcoord* v1, GGLcoord width) -{ - GGL_CONTEXT(c, con); - GGLcoord v[4][2]; - v[0][0] = v0[0]; v[0][1] = v0[1]; - v[1][0] = v1[0]; v[1][1] = v1[1]; - v0 = v[0]; - v1 = v[1]; - - const GGLcoord dx = v0[0] - v1[0]; - const GGLcoord dy = v0[1] - v1[1]; - GGLcoord nx = -dy; - GGLcoord ny = dx; - - // generally, this will be well below 1.0 - const GGLfixed norm = gglMulx(width, gglSqrtRecipx(nx*nx+ny*ny), 4); - nx = gglMulx(nx, norm, 21); - ny = gglMulx(ny, norm, 21); - - v[2][0] = v1[0]; v[2][1] = v1[1]; - v[3][0] = v0[0]; v[3][1] = v0[1]; - v[0][0] += nx; v[0][1] += ny; - v[1][0] += nx; v[1][1] += ny; - v[2][0] -= nx; v[2][1] -= ny; - v[3][0] -= nx; v[3][1] -= ny; - aapolyx(con, v[0], 4); -} - - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Rect -#endif - -void recti_validate(void *con, GGLint l, GGLint t, GGLint r, GGLint b) -{ - GGL_CONTEXT(c, con); - ggl_pick(c); - c->procs.recti = recti; - c->procs.recti(con, l, t, r, b); -} - -void recti(void* con, GGLint l, GGLint t, GGLint r, GGLint b) -{ - GGL_CONTEXT(c, con); - - // scissor... - if (l < GGLint(c->state.scissor.left)) - l = GGLint(c->state.scissor.left); - if (t < GGLint(c->state.scissor.top)) - t = GGLint(c->state.scissor.top); - if (r > GGLint(c->state.scissor.right)) - r = GGLint(c->state.scissor.right); - if (b > GGLint(c->state.scissor.bottom)) - b = GGLint(c->state.scissor.bottom); - - int xc = r - l; - int yc = b - t; - if (xc>0 && yc>0) { - c->iterators.xl = l; - c->iterators.xr = r; - c->init_y(c, t); - c->rect(c, yc); - } -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Triangle / Debugging -#endif - -static void scanline_set(context_t* c) -{ - int32_t x = c->iterators.xl; - size_t ct = c->iterators.xr - x; - int32_t y = c->iterators.y; - surface_t* cb = &(c->state.buffers.color); - const GGLFormat* fp = &(c->formats[cb->format]); - uint8_t* dst = reinterpret_cast<uint8_t*>(cb->data) + - (x + (cb->stride * y)) * fp->size; - const size_t size = ct * fp->size; - memset(dst, 0xFF, size); -} - -static void trianglex_debug(void* con, - const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2) -{ - GGL_CONTEXT(c, con); - if (c->state.needs.p & GGL_NEED_MASK(P_AA)) { - aa_trianglex(con,v0,v1,v2); - } else { - trianglex_big(con,v0,v1,v2); - } - void (*save_scanline)(context_t*) = c->scanline; - c->scanline = scanline_set; - linex(con, v0, v1, TRI_ONE); - linex(con, v1, v2, TRI_ONE); - linex(con, v2, v0, TRI_ONE); - c->scanline = save_scanline; -} - -static void trianglex_xor(void* con, - const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2) -{ - trianglex_big(con,v0,v1,v2); - trianglex_small(con,v0,v1,v2); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#pragma mark Triangle -#endif - -void trianglex_validate(void *con, - const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2) -{ - GGL_CONTEXT(c, con); - ggl_pick(c); - if (c->state.needs.p & GGL_NEED_MASK(P_AA)) { - c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : aa_trianglex; - } else { - c->procs.trianglex = DEBUG_TRANGLES ? trianglex_debug : trianglex_big; - } - c->procs.trianglex(con, v0, v1, v2); -} - -// ---------------------------------------------------------------------------- - -void trianglex_small(void* con, - const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2) -{ - GGL_CONTEXT(c, con); - - // vertices are in 28.4 fixed point, which allows - // us to use 32 bits multiplies below. - int32_t x0 = v0[0]; - int32_t y0 = v0[1]; - int32_t x1 = v1[0]; - int32_t y1 = v1[1]; - int32_t x2 = v2[0]; - int32_t y2 = v2[1]; - - int32_t dx01 = x0 - x1; - int32_t dy20 = y2 - y0; - int32_t dy01 = y0 - y1; - int32_t dx20 = x2 - x0; - - // The code below works only with CCW triangles - // so if we get a CW triangle, we need to swap two of its vertices - if (dx01*dy20 < dy01*dx20) { - swap(x0, x1); - swap(y0, y1); - dx01 = x0 - x1; - dy01 = y0 - y1; - dx20 = x2 - x0; - dy20 = y2 - y0; - } - int32_t dx12 = x1 - x2; - int32_t dy12 = y1 - y2; - - // bounding box & scissor - const int32_t bminx = TRI_FLOOR(min(x0, x1, x2)) >> TRI_FRACTION_BITS; - const int32_t bminy = TRI_FLOOR(min(y0, y1, y2)) >> TRI_FRACTION_BITS; - const int32_t bmaxx = TRI_CEIL( max(x0, x1, x2)) >> TRI_FRACTION_BITS; - const int32_t bmaxy = TRI_CEIL( max(y0, y1, y2)) >> TRI_FRACTION_BITS; - const int32_t minx = max(bminx, c->state.scissor.left); - const int32_t miny = max(bminy, c->state.scissor.top); - const int32_t maxx = min(bmaxx, c->state.scissor.right); - const int32_t maxy = min(bmaxy, c->state.scissor.bottom); - if ((minx >= maxx) || (miny >= maxy)) - return; // too small or clipped out... - - // step equations to the bounding box and snap to pixel center - const int32_t my = (miny << TRI_FRACTION_BITS) + TRI_HALF; - const int32_t mx = (minx << TRI_FRACTION_BITS) + TRI_HALF; - int32_t ey0 = dy01 * (x0 - mx) - dx01 * (y0 - my); - int32_t ey1 = dy12 * (x1 - mx) - dx12 * (y1 - my); - int32_t ey2 = dy20 * (x2 - mx) - dx20 * (y2 - my); - - // right-exclusive fill rule, to avoid rare cases - // of over drawing - if (dy01<0 || (dy01 == 0 && dx01>0)) ey0++; - if (dy12<0 || (dy12 == 0 && dx12>0)) ey1++; - if (dy20<0 || (dy20 == 0 && dx20>0)) ey2++; - - c->init_y(c, miny); - for (int32_t y = miny; y < maxy; y++) { - register int32_t ex0 = ey0; - register int32_t ex1 = ey1; - register int32_t ex2 = ey2; - register int32_t xl, xr; - for (xl=minx ; xl<maxx ; xl++) { - if (ex0>0 && ex1>0 && ex2>0) - break; // all strictly positive - ex0 -= dy01 << TRI_FRACTION_BITS; - ex1 -= dy12 << TRI_FRACTION_BITS; - ex2 -= dy20 << TRI_FRACTION_BITS; - } - xr = xl; - for ( ; xr<maxx ; xr++) { - if (!(ex0>0 && ex1>0 && ex2>0)) - break; // not all strictly positive - ex0 -= dy01 << TRI_FRACTION_BITS; - ex1 -= dy12 << TRI_FRACTION_BITS; - ex2 -= dy20 << TRI_FRACTION_BITS; - } - - if (xl < xr) { - c->iterators.xl = xl; - c->iterators.xr = xr; - c->scanline(c); - } - c->step_y(c); - - ey0 += dx01 << TRI_FRACTION_BITS; - ey1 += dx12 << TRI_FRACTION_BITS; - ey2 += dx20 << TRI_FRACTION_BITS; - } -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -// the following routine fills a triangle via edge stepping, which -// unfortunately requires divisions in the setup phase to get right, -// it should probably only be used for relatively large trianges - - -// x = y*DX/DY (ou DX and DY are constants, DY > 0, et y >= 0) -// -// for an equation of the type: -// x' = y*K/2^p (with K and p constants "carefully chosen") -// -// We can now do a DDA without precision loss. We define 'e' by: -// x' - x = y*(DX/DY - K/2^p) = y*e -// -// If we choose K = round(DX*2^p/DY) then, -// abs(e) <= 1/2^(p+1) by construction -// -// therefore abs(x'-x) = y*abs(e) <= y/2^(p+1) <= DY/2^(p+1) <= DMAX/2^(p+1) -// -// which means that if DMAX <= 2^p, therefore abs(x-x') <= 1/2, including -// at the last line. In fact, it's even a strict inequality except in one -// extrem case (DY == DMAX et e = +/- 1/2) -// -// Applying that to our coordinates, we need 2^p >= 4096*16 = 65536 -// so p = 16 is enough, we're so lucky! - -const int TRI_ITERATORS_BITS = 16; - -struct Edge -{ - int32_t x; // edge position in 16.16 coordinates - int32_t x_incr; // on each step, increment x by that amount - int32_t y_top; // starting scanline, 16.4 format - int32_t y_bot; -}; - -static void -edge_dump( Edge* edge ) -{ - LOGI( " top=%d (%.3f) bot=%d (%.3f) x=%d (%.3f) ix=%d (%.3f)", - edge->y_top, edge->y_top/float(TRI_ONE), - edge->y_bot, edge->y_bot/float(TRI_ONE), - edge->x, edge->x/float(FIXED_ONE), - edge->x_incr, edge->x_incr/float(FIXED_ONE) ); -} - -static void -triangle_dump_edges( Edge* edges, - int count ) -{ - LOGI( "%d edge%s:\n", count, count == 1 ? "" : "s" ); - for ( ; count > 0; count--, edges++ ) - edge_dump( edges ); -} - -// the following function sets up an edge, it assumes -// that ymin and ymax are in already in the 'reduced' -// format -static __attribute__((noinline)) -void edge_setup( - Edge* edges, - int* pcount, - const GGLcoord* p1, - const GGLcoord* p2, - int32_t ymin, - int32_t ymax ) -{ - const GGLfixed* top = p1; - const GGLfixed* bot = p2; - Edge* edge = edges + *pcount; - - if (top[1] > bot[1]) { - swap(top, bot); - } - - int y1 = top[1] | 1; - int y2 = bot[1] | 1; - int dy = y2 - y1; - - if ( dy == 0 || y1 > ymax || y2 < ymin ) - return; - - if ( y1 > ymin ) - ymin = TRI_SNAP_NEXT_HALF(y1); - - if ( y2 < ymax ) - ymax = TRI_SNAP_PREV_HALF(y2); - - if ( ymin > ymax ) // when the edge doesn't cross any scanline - return; - - const int x1 = top[0]; - const int dx = bot[0] - x1; - const int shift = TRI_ITERATORS_BITS - TRI_FRACTION_BITS; - - // setup edge fields - // We add 0.5 to edge->x here because it simplifies the rounding - // in triangle_sweep_edges() -- this doesn't change the ordering of 'x' - edge->x = (x1 << shift) + (1LU << (TRI_ITERATORS_BITS-1)); - edge->x_incr = 0; - edge->y_top = ymin; - edge->y_bot = ymax; - - if (ggl_likely(ymin <= ymax && dx)) { - edge->x_incr = gglDivQ16(dx, dy); - } - if (ggl_likely(y1 < ymin)) { - int32_t xadjust = (edge->x_incr * (ymin-y1)) >> TRI_FRACTION_BITS; - edge->x += xadjust; - } - - ++*pcount; -} - - -static void -triangle_sweep_edges( Edge* left, - Edge* right, - int ytop, - int ybot, - context_t* c ) -{ - int count = ((ybot - ytop)>>TRI_FRACTION_BITS) + 1; - if (count<=0) return; - - // sort the edges horizontally - if ((left->x > right->x) || - ((left->x == right->x) && (left->x_incr > right->x_incr))) { - swap(left, right); - } - - int left_x = left->x; - int right_x = right->x; - const int left_xi = left->x_incr; - const int right_xi = right->x_incr; - left->x += left_xi * count; - right->x += right_xi * count; - - const int xmin = c->state.scissor.left; - const int xmax = c->state.scissor.right; - do { - // horizontal scissoring - const int32_t xl = max(left_x >> TRI_ITERATORS_BITS, xmin); - const int32_t xr = min(right_x >> TRI_ITERATORS_BITS, xmax); - left_x += left_xi; - right_x += right_xi; - // invoke the scanline rasterizer - if (ggl_likely(xl < xr)) { - c->iterators.xl = xl; - c->iterators.xr = xr; - c->scanline(c); - } - c->step_y(c); - } while (--count); -} - - -void trianglex_big(void* con, - const GGLcoord* v0, const GGLcoord* v1, const GGLcoord* v2) -{ - GGL_CONTEXT(c, con); - - Edge edges[3]; - int num_edges = 0; - int32_t ymin = TRI_FROM_INT(c->state.scissor.top) + TRI_HALF; - int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom) - TRI_HALF; - - edge_setup( edges, &num_edges, v0, v1, ymin, ymax ); - edge_setup( edges, &num_edges, v0, v2, ymin, ymax ); - edge_setup( edges, &num_edges, v1, v2, ymin, ymax ); - - if (ggl_unlikely(num_edges<2)) // for really tiny triangles that don't - return; // cross any scanline centers - - Edge* left = &edges[0]; - Edge* right = &edges[1]; - Edge* other = &edges[2]; - int32_t y_top = min(left->y_top, right->y_top); - int32_t y_bot = max(left->y_bot, right->y_bot); - - if (ggl_likely(num_edges==3)) { - y_top = min(y_top, edges[2].y_top); - y_bot = max(y_bot, edges[2].y_bot); - if (edges[0].y_top > y_top) { - other = &edges[0]; - left = &edges[2]; - } else if (edges[1].y_top > y_top) { - other = &edges[1]; - right = &edges[2]; - } - } - - c->init_y(c, y_top >> TRI_FRACTION_BITS); - - int32_t y_mid = min(left->y_bot, right->y_bot); - triangle_sweep_edges( left, right, y_top, y_mid, c ); - - // second scanline sweep loop, if necessary - y_mid += TRI_ONE; - if (y_mid <= y_bot) { - ((left->y_bot == y_bot) ? right : left) = other; - if (other->y_top < y_mid) { - other->x += other->x_incr; - } - triangle_sweep_edges( left, right, y_mid, y_bot, c ); - } -} - -void aa_trianglex(void* con, - const GGLcoord* a, const GGLcoord* b, const GGLcoord* c) -{ - GGLcoord pts[6] = { a[0], a[1], b[0], b[1], c[0], c[1] }; - aapolyx(con, pts, 3); -} - -// ---------------------------------------------------------------------------- -#if 0 -#pragma mark - -#endif - -struct AAEdge -{ - GGLfixed x; // edge position in 12.16 coordinates - GGLfixed x_incr; // on each y step, increment x by that amount - GGLfixed y_incr; // on each x step, increment y by that amount - int16_t y_top; // starting scanline, 12.4 format - int16_t y_bot; // starting scanline, 12.4 format - void dump(); -}; - -void AAEdge::dump() -{ - float tri = 1.0f / TRI_ONE; - float iter = 1.0f / (1<<TRI_ITERATORS_BITS); - float fix = 1.0f / FIXED_ONE; - LOGD( "x=%08x (%.3f), " - "x_incr=%08x (%.3f), y_incr=%08x (%.3f), " - "y_top=%08x (%.3f), y_bot=%08x (%.3f) ", - x, x*fix, - x_incr, x_incr*iter, - y_incr, y_incr*iter, - y_top, y_top*tri, - y_bot, y_bot*tri ); -} - -// the following function sets up an edge, it assumes -// that ymin and ymax are in already in the 'reduced' -// format -static __attribute__((noinline)) -void aa_edge_setup( - AAEdge* edges, - int* pcount, - const GGLcoord* p1, - const GGLcoord* p2, - int32_t ymin, - int32_t ymax ) -{ - const GGLfixed* top = p1; - const GGLfixed* bot = p2; - AAEdge* edge = edges + *pcount; - - if (top[1] > bot[1]) - swap(top, bot); - - int y1 = top[1]; - int y2 = bot[1]; - int dy = y2 - y1; - - if (dy==0 || y1>ymax || y2<ymin) - return; - - if (y1 > ymin) - ymin = y1; - - if (y2 < ymax) - ymax = y2; - - const int x1 = top[0]; - const int dx = bot[0] - x1; - const int shift = FIXED_BITS - TRI_FRACTION_BITS; - - // setup edge fields - edge->x = x1 << shift; - edge->x_incr = 0; - edge->y_top = ymin; - edge->y_bot = ymax; - edge->y_incr = 0x7FFFFFFF; - - if (ggl_likely(ymin <= ymax && dx)) { - edge->x_incr = gglDivQ16(dx, dy); - if (dx != 0) { - edge->y_incr = abs(gglDivQ16(dy, dx)); - } - } - if (ggl_likely(y1 < ymin)) { - int32_t xadjust = (edge->x_incr * (ymin-y1)) - >> (TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS); - edge->x += xadjust; - } - - ++*pcount; -} - - -typedef int (*compar_t)(const void*, const void*); -static int compare_edges(const AAEdge *e0, const AAEdge *e1) { - if (e0->y_top > e1->y_top) return 1; - if (e0->y_top < e1->y_top) return -1; - if (e0->x > e1->x) return 1; - if (e0->x < e1->x) return -1; - if (e0->x_incr > e1->x_incr) return 1; - if (e0->x_incr < e1->x_incr) return -1; - return 0; // same edges, should never happen -} - -static inline -void SET_COVERAGE(int16_t*& p, int32_t value, ssize_t n) -{ - android_memset16((uint16_t*)p, value, n*2); - p += n; -} - -static inline -void ADD_COVERAGE(int16_t*& p, int32_t value) -{ - value = *p + value; - if (value >= 0x8000) - value = 0x7FFF; - *p++ = value; -} - -static inline -void SUB_COVERAGE(int16_t*& p, int32_t value) -{ - value = *p - value; - value &= ~(value>>31); - *p++ = value; -} - -void aapolyx(void* con, - const GGLcoord* pts, int count) -{ - /* - * NOTE: This routine assumes that the polygon has been clipped to the - * viewport already, that is, no vertex lies outside of the framebuffer. - * If this happens, the code below won't corrupt memory but the - * coverage values may not be correct. - */ - - GGL_CONTEXT(c, con); - - // we do only quads for now (it's used for thick lines) - if ((count>4) || (count<2)) return; - - // take scissor into account - const int xmin = c->state.scissor.left; - const int xmax = c->state.scissor.right; - if (xmin >= xmax) return; - - // generate edges from the vertices - int32_t ymin = TRI_FROM_INT(c->state.scissor.top); - int32_t ymax = TRI_FROM_INT(c->state.scissor.bottom); - if (ymin >= ymax) return; - - AAEdge edges[4]; - int num_edges = 0; - GGLcoord const * p = pts; - for (int i=0 ; i<count-1 ; i++, p+=2) { - aa_edge_setup(edges, &num_edges, p, p+2, ymin, ymax); - } - aa_edge_setup(edges, &num_edges, p, pts, ymin, ymax ); - if (ggl_unlikely(num_edges<2)) - return; - - // sort the edge list top to bottom, left to right. - qsort(edges, num_edges, sizeof(AAEdge), (compar_t)compare_edges); - - int16_t* const covPtr = c->state.buffers.coverage; - memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr)); - - // now, sweep all edges in order - // start with the 2 first edges. We know that they share their top - // vertex, by construction. - int i = 2; - AAEdge* left = &edges[0]; - AAEdge* right = &edges[1]; - int32_t yt = left->y_top; - GGLfixed l = left->x; - GGLfixed r = right->x; - int retire = 0; - int16_t* coverage; - - // at this point we can initialize the rasterizer - c->init_y(c, yt>>TRI_FRACTION_BITS); - c->iterators.xl = xmax; - c->iterators.xr = xmin; - - do { - int32_t y = min(min(left->y_bot, right->y_bot), TRI_FLOOR(yt + TRI_ONE)); - const int32_t shift = TRI_FRACTION_BITS + TRI_ITERATORS_BITS - FIXED_BITS; - const int cf_shift = (1 + TRI_FRACTION_BITS*2 + TRI_ITERATORS_BITS - 15); - - // compute xmin and xmax for the left edge - GGLfixed l_min = gglMulAddx(left->x_incr, y - left->y_top, left->x, shift); - GGLfixed l_max = l; - l = l_min; - if (l_min > l_max) - swap(l_min, l_max); - - // compute xmin and xmax for the right edge - GGLfixed r_min = gglMulAddx(right->x_incr, y - right->y_top, right->x, shift); - GGLfixed r_max = r; - r = r_min; - if (r_min > r_max) - swap(r_min, r_max); - - // make sure we're not touching coverage values outside of the - // framebuffer - l_min &= ~(l_min>>31); - r_min &= ~(r_min>>31); - l_max &= ~(l_max>>31); - r_max &= ~(r_max>>31); - if (gglFixedToIntFloor(l_min) >= xmax) l_min = gglIntToFixed(xmax)-1; - if (gglFixedToIntFloor(r_min) >= xmax) r_min = gglIntToFixed(xmax)-1; - if (gglFixedToIntCeil(l_max) >= xmax) l_max = gglIntToFixed(xmax)-1; - if (gglFixedToIntCeil(r_max) >= xmax) r_max = gglIntToFixed(xmax)-1; - - // compute the integer versions of the above - const GGLfixed l_min_i = gglFloorx(l_min); - const GGLfixed l_max_i = gglCeilx (l_max); - const GGLfixed r_min_i = gglFloorx(r_min); - const GGLfixed r_max_i = gglCeilx (r_max); - - // clip horizontally using the scissor - const int xml = max(xmin, gglFixedToIntFloor(l_min_i)); - const int xmr = min(xmax, gglFixedToIntFloor(r_max_i)); - - // if we just stepped to a new scanline, render the previous one. - // and clear the coverage buffer - if (retire) { - if (c->iterators.xl < c->iterators.xr) - c->scanline(c); - c->step_y(c); - memset(covPtr+xmin, 0, (xmax-xmin)*sizeof(*covPtr)); - c->iterators.xl = xml; - c->iterators.xr = xmr; - } else { - // update the horizontal range of this scanline - c->iterators.xl = min(c->iterators.xl, xml); - c->iterators.xr = max(c->iterators.xr, xmr); - } - - coverage = covPtr + gglFixedToIntFloor(l_min_i); - if (l_min_i == gglFloorx(l_max)) { - - /* - * fully traverse this pixel vertically - * l_max - * +-----/--+ yt - * | / | - * | / | - * | / | - * +-/------+ y - * l_min (l_min_i + TRI_ONE) - */ - - GGLfixed dx = l_max - l_min; - int32_t dy = y - yt; - int cf = gglMulx((dx >> 1) + (l_min_i + FIXED_ONE - l_max), dy, - FIXED_BITS + TRI_FRACTION_BITS - 15); - ADD_COVERAGE(coverage, cf); - // all pixels on the right have cf = 1.0 - } else { - /* - * spans several pixels in one scanline - * l_max - * +--------+--/-----+ yt - * | |/ | - * | /| | - * | / | | - * +---/----+--------+ y - * l_min (l_min_i + TRI_ONE) - */ - - // handle the first pixel separately... - const int32_t y_incr = left->y_incr; - int32_t dx = TRI_FROM_FIXED(l_min_i - l_min) + TRI_ONE; - int32_t cf = (dx * dx * y_incr) >> cf_shift; - ADD_COVERAGE(coverage, cf); - - // following pixels get covered by y_incr, but we need - // to fix-up the cf to account for previous partial pixel - dx = TRI_FROM_FIXED(l_min - l_min_i); - cf -= (dx * dx * y_incr) >> cf_shift; - for (int x = l_min_i+FIXED_ONE ; x < l_max_i-FIXED_ONE ; x += FIXED_ONE) { - cf += y_incr >> (TRI_ITERATORS_BITS-15); - ADD_COVERAGE(coverage, cf); - } - - // and the last pixel - dx = TRI_FROM_FIXED(l_max - l_max_i) - TRI_ONE; - cf += (dx * dx * y_incr) >> cf_shift; - ADD_COVERAGE(coverage, cf); - } - - // now, fill up all fully covered pixels - coverage = covPtr + gglFixedToIntFloor(l_max_i); - int cf = ((y - yt) << (15 - TRI_FRACTION_BITS)); - if (ggl_likely(cf >= 0x8000)) { - SET_COVERAGE(coverage, 0x7FFF, ((r_max - l_max_i)>>FIXED_BITS)+1); - } else { - for (int x=l_max_i ; x<r_max ; x+=FIXED_ONE) { - ADD_COVERAGE(coverage, cf); - } - } - - // subtract the coverage of the right edge - coverage = covPtr + gglFixedToIntFloor(r_min_i); - if (r_min_i == gglFloorx(r_max)) { - GGLfixed dx = r_max - r_min; - int32_t dy = y - yt; - int cf = gglMulx((dx >> 1) + (r_min_i + FIXED_ONE - r_max), dy, - FIXED_BITS + TRI_FRACTION_BITS - 15); - SUB_COVERAGE(coverage, cf); - // all pixels on the right have cf = 1.0 - } else { - // handle the first pixel separately... - const int32_t y_incr = right->y_incr; - int32_t dx = TRI_FROM_FIXED(r_min_i - r_min) + TRI_ONE; - int32_t cf = (dx * dx * y_incr) >> cf_shift; - SUB_COVERAGE(coverage, cf); - - // following pixels get covered by y_incr, but we need - // to fix-up the cf to account for previous partial pixel - dx = TRI_FROM_FIXED(r_min - r_min_i); - cf -= (dx * dx * y_incr) >> cf_shift; - for (int x = r_min_i+FIXED_ONE ; x < r_max_i-FIXED_ONE ; x += FIXED_ONE) { - cf += y_incr >> (TRI_ITERATORS_BITS-15); - SUB_COVERAGE(coverage, cf); - } - - // and the last pixel - dx = TRI_FROM_FIXED(r_max - r_max_i) - TRI_ONE; - cf += (dx * dx * y_incr) >> cf_shift; - SUB_COVERAGE(coverage, cf); - } - - // did we reach the end of an edge? if so, get a new one. - if (y == left->y_bot || y == right->y_bot) { - // bail out if we're done - if (i>=num_edges) - break; - if (y == left->y_bot) - left = &edges[i++]; - if (y == right->y_bot) - right = &edges[i++]; - } - - // next scanline - yt = y; - - // did we just finish a scanline? - retire = (y << (32-TRI_FRACTION_BITS)) == 0; - } while (true); - - // render the last scanline - if (c->iterators.xl < c->iterators.xr) - c->scanline(c); -} - -}; // namespace android diff --git a/libpixelflinger/trap.h b/libpixelflinger/trap.h deleted file mode 100644 index 7cce7b3e15edc2c091401efd84c307e779f05b68..0000000000000000000000000000000000000000 --- a/libpixelflinger/trap.h +++ /dev/null @@ -1,31 +0,0 @@ -/* libs/pixelflinger/trap.h -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - - -#ifndef ANDROID_TRAP_H -#define ANDROID_TRAP_H - -#include <private/pixelflinger/ggl_context.h> - -namespace android { - -void ggl_init_trap(context_t* c); -void ggl_state_changed(context_t* c, int flags); - -}; // namespace android - -#endif diff --git a/libzipfile/Android.mk b/libzipfile/Android.mk deleted file mode 100644 index d2d758cc2c83f0641e534fae9f7a0a3ee9e5a081..0000000000000000000000000000000000000000 --- a/libzipfile/Android.mk +++ /dev/null @@ -1,48 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -# build host static library -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - centraldir.c \ - zipfile.c - -LOCAL_STATIC_LIBRARIES := \ - libunz - -LOCAL_MODULE:= libzipfile - -LOCAL_C_INCLUDES += external/zlib - -include $(BUILD_HOST_STATIC_LIBRARY) - -# build device static library -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - centraldir.c \ - zipfile.c - -LOCAL_STATIC_LIBRARIES := \ - libunz - -LOCAL_MODULE:= libzipfile - -LOCAL_C_INCLUDES += external/zlib - -include $(BUILD_STATIC_LIBRARY) - - -# build test_zipfile -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - test_zipfile.c - -LOCAL_STATIC_LIBRARIES := libzipfile libunz - -LOCAL_MODULE := test_zipfile - -LOCAL_C_INCLUDES += external/zlib - -include $(BUILD_HOST_EXECUTABLE) diff --git a/libzipfile/MODULE_LICENSE_APACHE2 b/libzipfile/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/libzipfile/NOTICE b/libzipfile/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/libzipfile/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/libzipfile/centraldir.c b/libzipfile/centraldir.c deleted file mode 100644 index 4387cebaa0e4faf4c03fe159610a239638c2ee6e..0000000000000000000000000000000000000000 --- a/libzipfile/centraldir.c +++ /dev/null @@ -1,256 +0,0 @@ -#include "private.h" -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -enum { - // finding the directory - CD_SIGNATURE = 0x06054b50, - EOCD_LEN = 22, // EndOfCentralDir len, excl. comment - MAX_COMMENT_LEN = 65535, - MAX_EOCD_SEARCH = MAX_COMMENT_LEN + EOCD_LEN, - - // central directory entries - ENTRY_SIGNATURE = 0x02014b50, - ENTRY_LEN = 46, // CentralDirEnt len, excl. var fields - - // local file header - LFH_SIZE = 30, -}; - -unsigned int -read_le_int(const unsigned char* buf) -{ - return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); -} - -unsigned int -read_le_short(const unsigned char* buf) -{ - return buf[0] | (buf[1] << 8); -} - -static int -read_central_dir_values(Zipfile* file, const unsigned char* buf, int len) -{ - if (len < EOCD_LEN) { - // looks like ZIP file got truncated - fprintf(stderr, " Zip EOCD: expected >= %d bytes, found %d\n", - EOCD_LEN, len); - return -1; - } - - file->disknum = read_le_short(&buf[0x04]); - file->diskWithCentralDir = read_le_short(&buf[0x06]); - file->entryCount = read_le_short(&buf[0x08]); - file->totalEntryCount = read_le_short(&buf[0x0a]); - file->centralDirSize = read_le_int(&buf[0x0c]); - file->centralDirOffest = read_le_int(&buf[0x10]); - file->commentLen = read_le_short(&buf[0x14]); - - if (file->commentLen > 0) { - if (EOCD_LEN + file->commentLen > len) { - fprintf(stderr, "EOCD(%d) + comment(%d) exceeds len (%d)\n", - EOCD_LEN, file->commentLen, len); - return -1; - } - file->comment = buf + EOCD_LEN; - } - - return 0; -} - -static int -read_central_directory_entry(Zipfile* file, Zipentry* entry, - const unsigned char** buf, ssize_t* len) -{ - const unsigned char* p; - - unsigned short versionMadeBy; - unsigned short versionToExtract; - unsigned short gpBitFlag; - unsigned short compressionMethod; - unsigned short lastModFileTime; - unsigned short lastModFileDate; - unsigned long crc32; - unsigned long compressedSize; - unsigned long uncompressedSize; - unsigned short extraFieldLength; - unsigned short fileCommentLength; - unsigned short diskNumberStart; - unsigned short internalAttrs; - unsigned long externalAttrs; - unsigned long localHeaderRelOffset; - const unsigned char* extraField; - const unsigned char* fileComment; - unsigned int dataOffset; - unsigned short lfhExtraFieldSize; - - - p = *buf; - - if (*len < ENTRY_LEN) { - fprintf(stderr, "cde entry not large enough\n"); - return -1; - } - - if (read_le_int(&p[0x00]) != ENTRY_SIGNATURE) { - fprintf(stderr, "Whoops: didn't find expected signature\n"); - return -1; - } - - versionMadeBy = read_le_short(&p[0x04]); - versionToExtract = read_le_short(&p[0x06]); - gpBitFlag = read_le_short(&p[0x08]); - entry->compressionMethod = read_le_short(&p[0x0a]); - lastModFileTime = read_le_short(&p[0x0c]); - lastModFileDate = read_le_short(&p[0x0e]); - crc32 = read_le_int(&p[0x10]); - compressedSize = read_le_int(&p[0x14]); - entry->uncompressedSize = read_le_int(&p[0x18]); - entry->fileNameLength = read_le_short(&p[0x1c]); - extraFieldLength = read_le_short(&p[0x1e]); - fileCommentLength = read_le_short(&p[0x20]); - diskNumberStart = read_le_short(&p[0x22]); - internalAttrs = read_le_short(&p[0x24]); - externalAttrs = read_le_int(&p[0x26]); - localHeaderRelOffset = read_le_int(&p[0x2a]); - - p += ENTRY_LEN; - - // filename - if (entry->fileNameLength != 0) { - entry->fileName = p; - } else { - entry->fileName = NULL; - } - p += entry->fileNameLength; - - // extra field - if (extraFieldLength != 0) { - extraField = p; - } else { - extraField = NULL; - } - p += extraFieldLength; - - // comment, if any - if (fileCommentLength != 0) { - fileComment = p; - } else { - fileComment = NULL; - } - p += fileCommentLength; - - *buf = p; - - // the size of the extraField in the central dir is how much data there is, - // but the one in the local file header also contains some padding. - p = file->buf + localHeaderRelOffset; - extraFieldLength = read_le_short(&p[0x1c]); - - dataOffset = localHeaderRelOffset + LFH_SIZE - + entry->fileNameLength + extraFieldLength; - entry->data = file->buf + dataOffset; -#if 0 - printf("file->buf=%p entry->data=%p dataOffset=%x localHeaderRelOffset=%d " - "entry->fileNameLength=%d extraFieldLength=%d\n", - file->buf, entry->data, dataOffset, localHeaderRelOffset, - entry->fileNameLength, extraFieldLength); -#endif - return 0; -} - -/* - * Find the central directory and read the contents. - * - * The fun thing about ZIP archives is that they may or may not be - * readable from start to end. In some cases, notably for archives - * that were written to stdout, the only length information is in the - * central directory at the end of the file. - * - * Of course, the central directory can be followed by a variable-length - * comment field, so we have to scan through it backwards. The comment - * is at most 64K, plus we have 18 bytes for the end-of-central-dir stuff - * itself, plus apparently sometimes people throw random junk on the end - * just for the fun of it. - * - * This is all a little wobbly. If the wrong value ends up in the EOCD - * area, we're hosed. This appears to be the way that everbody handles - * it though, so we're in pretty good company if this fails. - */ -int -read_central_dir(Zipfile *file) -{ - int err; - - const unsigned char* buf = file->buf; - ssize_t bufsize = file->bufsize; - const unsigned char* eocd; - const unsigned char* p; - const unsigned char* start; - ssize_t len; - int i; - - // too small to be a ZIP archive? - if (bufsize < EOCD_LEN) { - fprintf(stderr, "Length is %d -- too small\n", bufsize); - goto bail; - } - - // find the end-of-central-dir magic - if (bufsize > MAX_EOCD_SEARCH) { - start = buf + bufsize - MAX_EOCD_SEARCH; - } else { - start = buf; - } - p = buf + bufsize - 4; - while (p >= start) { - if (*p == 0x50 && read_le_int(p) == CD_SIGNATURE) { - eocd = p; - break; - } - p--; - } - if (p < start) { - fprintf(stderr, "EOCD not found, not Zip\n"); - goto bail; - } - - // extract eocd values - err = read_central_dir_values(file, eocd, (buf+bufsize)-eocd); - if (err != 0) { - goto bail; - } - - if (file->disknum != 0 - || file->diskWithCentralDir != 0 - || file->entryCount != file->totalEntryCount) { - fprintf(stderr, "Archive spanning not supported\n"); - goto bail; - } - - // Loop through and read the central dir entries. - p = buf + file->centralDirOffest; - len = (buf+bufsize)-p; - for (i=0; i < file->totalEntryCount; i++) { - Zipentry* entry = malloc(sizeof(Zipentry)); - memset(entry, sizeof(Zipentry), 0); - - err = read_central_directory_entry(file, entry, &p, &len); - if (err != 0) { - fprintf(stderr, "read_central_directory_entry failed\n"); - free(entry); - goto bail; - } - - // add it to our list - entry->next = file->entries; - file->entries = entry; - } - - return 0; -bail: - return -1; -} - diff --git a/libzipfile/private.h b/libzipfile/private.h deleted file mode 100644 index 06f788dd6ee6a6981ab0adeb879b20ddb628c9cf..0000000000000000000000000000000000000000 --- a/libzipfile/private.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef PRIVATE_H -#define PRIVATE_H - -#include <stddef.h> -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -typedef struct Zipentry { - unsigned long fileNameLength; - const unsigned char* fileName; - unsigned short compressionMethod; - unsigned int uncompressedSize; - unsigned int compressedSize; - const unsigned char* data; - - struct Zipentry* next; -} Zipentry; - -typedef struct Zipfile -{ - const unsigned char *buf; - ssize_t bufsize; - - // Central directory - unsigned short disknum; //mDiskNumber; - unsigned short diskWithCentralDir; //mDiskWithCentralDir; - unsigned short entryCount; //mNumEntries; - unsigned short totalEntryCount; //mTotalNumEntries; - unsigned int centralDirSize; //mCentralDirSize; - unsigned int centralDirOffest; // offset from first disk //mCentralDirOffset; - unsigned short commentLen; //mCommentLen; - const unsigned char* comment; //mComment; - - Zipentry* entries; -} Zipfile; - -int read_central_dir(Zipfile* file); - -unsigned int read_le_int(const unsigned char* buf); -unsigned int read_le_short(const unsigned char* buf); - -#endif // PRIVATE_H - diff --git a/libzipfile/test_zipfile.c b/libzipfile/test_zipfile.c deleted file mode 100644 index 40840ec205148061230ae0390ac754fb18a17a96..0000000000000000000000000000000000000000 --- a/libzipfile/test_zipfile.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <zipfile/zipfile.h> - -#include <stdio.h> -#include <stdlib.h> - -void dump_zipfile(FILE* to, zipfile_t file); - -int -main(int argc, char** argv) -{ - FILE* f; - size_t size, unsize; - void* buf; - void* scratch; - zipfile_t zip; - zipentry_t entry; - int err; - enum { HUH, LIST, UNZIP } what = HUH; - - if (strcmp(argv[2], "-l") == 0 && argc == 3) { - what = LIST; - } - else if (strcmp(argv[2], "-u") == 0 && argc == 5) { - what = UNZIP; - } - else { - fprintf(stderr, "usage: test_zipfile ZIPFILE -l\n" - " lists the files in the zipfile\n" - " test_zipfile ZIPFILE -u FILENAME SAVETO\n" - " saves FILENAME from the zip file into SAVETO\n"); - return 1; - } - - f = fopen(argv[1], "r"); - if (f == NULL) { - fprintf(stderr, "couldn't open %s\n", argv[1]); - return 1; - } - - fseek(f, 0, SEEK_END); - size = ftell(f); - rewind(f); - - buf = malloc(size); - fread(buf, 1, size, f); - - zip = init_zipfile(buf, size); - if (zip == NULL) { - fprintf(stderr, "inti_zipfile failed\n"); - return 1; - } - - fclose(f); - - - switch (what) - { - case LIST: - dump_zipfile(stdout, zip); - break; - case UNZIP: - entry = lookup_zipentry(zip, argv[3]); - if (entry == NULL) { - fprintf(stderr, "zip file '%s' does not contain file '%s'\n", - argv[1], argv[1]); - return 1; - } - f = fopen(argv[4], "w"); - if (f == NULL) { - fprintf(stderr, "can't open file for writing '%s'\n", argv[4]); - return 1; - } - unsize = get_zipentry_size(entry); - size = unsize * 1.001; - scratch = malloc(size); - printf("scratch=%p\n", scratch); - err = decompress_zipentry(entry, scratch, size); - if (err != 0) { - fprintf(stderr, "error decompressing file\n"); - return 1; - } - fwrite(scratch, unsize, 1, f); - free(scratch); - fclose(f); - break; - } - - free(buf); - - return 0; -} - diff --git a/libzipfile/zipfile.c b/libzipfile/zipfile.c deleted file mode 100644 index b52d02df758b12c74efbc3d6568687e377b4c6e8..0000000000000000000000000000000000000000 --- a/libzipfile/zipfile.c +++ /dev/null @@ -1,160 +0,0 @@ -#include <zipfile/zipfile.h> - -#include "private.h" -#include <stdlib.h> -#include <string.h> -#include <zlib.h> -#define DEF_MEM_LEVEL 8 // normally in zutil.h? - -zipfile_t -init_zipfile(const void* data, size_t size) -{ - int err; - - Zipfile *file = malloc(sizeof(Zipfile)); - if (file == NULL) return NULL; - memset(file, 0, sizeof(Zipfile)); - file->buf = data; - file->bufsize = size; - - err = read_central_dir(file); - if (err != 0) goto fail; - - return file; -fail: - free(file); - return NULL; -} - -void -release_zipfile(zipfile_t f) -{ - Zipfile* file = (Zipfile*)f; - Zipentry* entry = file->entries; - while (entry) { - Zipentry* next = entry->next; - free(entry); - entry = next; - } - free(file); -} - -zipentry_t -lookup_zipentry(zipfile_t f, const char* entryName) -{ - Zipfile* file = (Zipfile*)f; - Zipentry* entry = file->entries; - while (entry) { - if (0 == memcmp(entryName, entry->fileName, entry->fileNameLength)) { - return entry; - } - entry = entry->next; - } - return NULL; -} - -size_t -get_zipentry_size(zipentry_t entry) -{ - return ((Zipentry*)entry)->uncompressedSize; -} - -char* -get_zipentry_name(zipentry_t entry) -{ - Zipentry* e = (Zipentry*)entry; - int l = e->fileNameLength; - char* s = malloc(l+1); - memcpy(s, e->fileName, l); - s[l] = '\0'; - return s; -} - -enum { - STORED = 0, - DEFLATED = 8 -}; - -static int -uninflate(unsigned char* out, int unlen, const unsigned char* in, int clen) -{ - z_stream zstream; - unsigned long crc; - int err = 0; - int zerr; - - memset(&zstream, 0, sizeof(zstream)); - zstream.zalloc = Z_NULL; - zstream.zfree = Z_NULL; - zstream.opaque = Z_NULL; - zstream.next_in = (void*)in; - zstream.avail_in = unlen; - zstream.next_out = (Bytef*) out; - zstream.avail_out = unlen; - zstream.data_type = Z_UNKNOWN; - - // Use the undocumented "negative window bits" feature to tell zlib - // that there's no zlib header waiting for it. - zerr = inflateInit2(&zstream, -MAX_WBITS); - if (zerr != Z_OK) { - return -1; - } - - // uncompress the data - zerr = inflate(&zstream, Z_FINISH); - if (zerr != Z_STREAM_END) { - fprintf(stderr, "zerr=%d Z_STREAM_END=%d total_out=%lu\n", zerr, Z_STREAM_END, - zstream.total_out); - err = -1; - } - - inflateEnd(&zstream); - return err; -} - -int -decompress_zipentry(zipentry_t e, void* buf, int bufsize) -{ - Zipentry* entry = (Zipentry*)e; - switch (entry->compressionMethod) - { - case STORED: - memcpy(buf, entry->data, entry->uncompressedSize); - return 0; - case DEFLATED: - return uninflate(buf, bufsize, entry->data, entry->compressedSize); - default: - return -1; - } -} - -void -dump_zipfile(FILE* to, zipfile_t file) -{ - Zipfile* zip = (Zipfile*)file; - Zipentry* entry = zip->entries; - int i; - - fprintf(to, "entryCount=%d\n", zip->entryCount); - for (i=0; i<zip->entryCount; i++) { - fprintf(to, " file \""); - fwrite(entry->fileName, entry->fileNameLength, 1, to); - fprintf(to, "\"\n"); - entry = entry->next; - } -} - -zipentry_t -iterate_zipfile(zipfile_t file, void** cookie) -{ - Zipentry* entry = (Zipentry*)*cookie; - if (entry == NULL) { - Zipfile* zip = (Zipfile*)file; - *cookie = zip->entries; - return *cookie; - } else { - entry = entry->next; - *cookie = entry; - return entry; - } -} diff --git a/logcat/Android.mk b/logcat/Android.mk deleted file mode 100644 index 3ee051d71fa3bcdb4984bcf61a07fa41f6e1c255..0000000000000000000000000000000000000000 --- a/logcat/Android.mk +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright 2006 The Android Open Source Project - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= logcat.cpp - -LOCAL_SHARED_LIBRARIES := liblog - -LOCAL_MODULE:= logcat - -include $(BUILD_EXECUTABLE) - -######################## -include $(CLEAR_VARS) - -LOCAL_MODULE := event-log-tags - -#LOCAL_MODULE_TAGS := user development - -# This will install the file in /system/etc -# -LOCAL_MODULE_CLASS := ETC - -LOCAL_SRC_FILES := $(LOCAL_MODULE) - -include $(BUILD_PREBUILT) diff --git a/logcat/MODULE_LICENSE_APACHE2 b/logcat/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/logcat/NOTICE b/logcat/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/logcat/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/logcat/event-log-tags b/logcat/event-log-tags deleted file mode 100644 index d2eff60fa802df3a64a0778f61f6e869b1d65bb6..0000000000000000000000000000000000000000 --- a/logcat/event-log-tags +++ /dev/null @@ -1,346 +0,0 @@ -# The entries in this file map a sparse set of log tag numbers to tag names. -# This is installed on the device, in /system/etc, and parsed by logcat. -# -# Tag numbers are decimal integers, from 0 to 2^31. (Let's leave the -# negative values alone for now.) -# -# Tag names are one or more ASCII letters and numbers or underscores, i.e. -# "[A-Z][a-z][0-9]_". Do not include spaces or punctuation (the former -# impacts log readability, the latter makes regex searches more annoying). -# -# Tag numbers and names are separated by whitespace. Blank lines and lines -# starting with '#' are ignored. -# -# Optionally, after the tag names can be put a description for the value(s) -# of the tag. Description are in the format -# (<name>|data type[|data unit]) -# Multiple values are separated by commas. -# -# The data type is a number from the following values: -# 1: int -# 2: long -# 3: string -# 4: list -# -# The data unit is a number taken from the following list: -# 1: Number of objects -# 2: Number of bytes -# 3: Number of milliseconds -# 4: Number of allocations -# 5: Id -# 6: Percent -# Default value for data of type int/long is 2 (bytes). -# -# TODO: generate ".java" and ".h" files with integer constants from this file. - -# These are used for testing, do not modify without updating -# tests/framework-tests/src/android/util/EventLogFunctionalTest.java. -42 answer (to life the universe etc|3) -314 pi -2718 e - -2719 configuration_changed (config mask|1|5) -2720 sync (id|3),(event|1|5),(source|1|5) -2721 cpu (total|1|6),(user|1|6),(system|1|6),(iowait|1|6),(irq|1|6),(softirq|1|6) -2722 battery_level (level|1|6),(voltage|1|1),(temperature|1|1) -2723 battery_status (status|1|5),(health|1|5),(present|1|5),(plugged|1|5),(technology|3) -# This is logged when the device is being forced to sleep (typically by -# the user pressing the power button). -2724 power_sleep_requested (wakeLocksCleared|1|1) -# This is logged when the screen on broadcast has completed -2725 power_screen_broadcast_send (wakelockCount|1|1) -# This is logged when the screen broadcast has completed -2726 power_screen_broadcast_done (on|1|5),(broadcastDuration|2|3),(wakelockCount|1|1) -# This is logged when the screen on broadcast has completed -2727 power_screen_broadcast_stop (which|1|5),(wakelockCount|1|1) -# This is logged when the screen is turned on or off. -2728 power_screen_state (offOrOn|1|5),(becauseOfUser|1|5),(totalTouchDownTime|2|3),(touchCycles|1|1) -# This is logged when the partial wake lock (keeping the device awake -# regardless of whether the screen is off) is acquired or released. -2729 power_partial_wake_state (releasedorAcquired|1|5),(tag|3) -# This is logged when battery goes from discharging to charging. -# It lets us count the total amount of time between charges and the discharge level -2730 battery_discharge (duration|2|3),(minLevel|1|6),(maxLevel|1|6) -# -# Leave IDs through 2739 for more power logs -# - -# This event is logged when the location service uploads location data. -2740 location_controller -# This event is logged when someone is deciding to force a garbage collection -2741 force_gc (reason|3) -# This event is logged on each tickle -2742 tickle (authority|3) -# What happens in a sync operation (bytes sent and received, and -# operation details) -2743 sync_details (authority|3),(send|1|2),(recv|1|2),(details|3) - -# The disk space free on the /data partition, in bytes -2744 free_storage_changed (data|2|2) -# Device low memory notification and disk space free on the /data partition, in bytes at that time -2745 low_storage (data|2|2) -# disk space free on the /data partition in bytes -2746 free_storage_left (data|2|2) - -# when a NotificationManager.notify is called -2750 notification_enqueue (pkg|3),(id|1|5),(notification|3) -# when someone tries to cancel a notification, the notification manager sometimes -# calls this with flags too -2751 notification_cancel (pkg|3),(id|1|5),(required_flags|1) -# when someone tries to cancel all of the notifications for a particular package -2752 notification_cancel_all (pkg|3),(required_flags|1) - -# This event is logged when GTalkService encounters important events -2800 gtalkservice (eventType|1) -# This event is logged for GTalk connection state changes. The status field is an int, but -# it really contains 4 separate values, each taking up a byte -# (eventType, connection state, connection error, network state) -2801 gtalk_connection (status|1) - -2802 watchdog (Service|3) -2803 watchdog_proc_pss (Process|3),(Pid|1|5),(Pss|1|2) -2804 watchdog_soft_reset (Process|3),(Pid|1|5),(MaxPss|1|2),(Pss|1|2),(Skip|3) -2805 watchdog_hard_reset (Process|3),(Pid|1|5),(MaxPss|1|2),(Pss|1|2) -2806 watchdog_pss_stats (EmptyPss|1|2),(EmptyCount|1|1),(BackgroundPss|1|2),(BackgroundCount|1|1),(ServicePss|1|2),(ServiceCount|1|1),(VisiblePss|1|2),(VisibleCount|1|1),(ForegroundPss|1|2),(ForegroundCount|1|1),(NoPssCount|1|1) -2807 watchdog_proc_stats (DeathsInOne|1|1),(DeathsInTwo|1|1),(DeathsInThree|1|1),(DeathsInFour|1|1),(DeathsInFive|1|1) -2808 watchdog_scheduled_reboot (Now|2|1),(Interval|1|3),(StartTime|1|3),(Window|1|3),(Skip|3) -2809 watchdog_meminfo (MemFree|1|2),(Buffers|1|2),(Cached|1|2),(Active|1|2),(Inactive|1|2),(AnonPages|1|2),(Mapped|1|2),(Slab|1|2),(SReclaimable|1|2),(SUnreclaim|1|2),(PageTables|1|2) -2810 watchdog_vmstat (runtime|2|3),(pgfree|1|1),(pgactivate|1|1),(pgdeactivate|1|1),(pgfault|1|1),(pgmajfault|1|1) -2811 watchdog_requested_reboot (NoWait|1|1),(ScheduleInterval|1|3),(RecheckInterval|1|3),(StartTime|1|3),(Window|1|3),(MinScreenOff|1|3),(MinNextAlarm|1|3) - -# Device boot timings. We include monotonic clock values because the -# intrinsic event log times are wall-clock. -# -# Runtime starts: -3000 boot_progress_start (time|2|3) -# SystemServer.run() starts: -3010 boot_progress_system_run (time|2|3) -# ZygoteInit class preloading starts: -3020 boot_progress_preload_start (time|2|3) -# ZygoteInit class preloading ends: -3030 boot_progress_preload_end (time|2|3) -# ActivityManagerService.systemReady() starts: -3040 boot_progress_ams_ready (time|2|3) -# ActivityManagerService calls enableScreenAfterBoot(): -3050 boot_progress_enable_screen (time|2|3) -# Package Manager starts: -3060 boot_progress_pms_start (time|2|3) -# Package Manager .apk scan starts: -3070 boot_progress_pms_system_scan_start (time|2|3) -# Package Manager .apk scan starts: -3080 boot_progress_pms_data_scan_start (time|2|3) -# Package Manager .apk scan ends: -3090 boot_progress_pms_scan_end (time|2|3) -# Package Manager ready: -3100 boot_progress_pms_ready (time|2|3) -# + check activity_launch_time for Home app - -# Do not change these names without updating the checkin_events setting in -# google3/googledata/wireless/android/provisioning/gservices.config !! -# -# An activity is being finished: -30001 am_finish_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Reason|3) -# A task is being brought to the front of the screen: -30002 am_task_to_front (Task|1|5) -# An existing activity is being given a new intent: -30003 am_new_intent (Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5) -# A new task is being created: -30004 am_create_task (Task ID|1|5) -# A new activity is being created in an existing task: -30005 am_create_activity (Token|1|5),(Task ID|1|5),(Component Name|3),(Action|3),(MIME Type|3),(URI|3),(Flags|1|5) -# An activity has been resumed into the foreground but was not already running: -30006 am_restart_activity (Token|1|5),(Task ID|1|5),(Component Name|3) -# An activity has been resumed and is now in the foreground: -30007 am_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3) -# Application Not Responding -30008 anr (pid|1|5),(Package Name|3),(reason|3) -# Activity launch time -30009 activity_launch_time (Token|1|5),(Component Name|3),(time|2|3) -# Application process bound to work -30010 am_proc_bound (PID|1|5),(Process Name|3) -# Application process died -30011 am_proc_died (PID|1|5),(Process Name|3) -# The Activity Manager failed to pause the given activity. -30012 am_failed_to_pause (Token|1|5),(Wanting to pause|3),(Currently pausing|3) -# Attempting to pause the current activity -30013 am_pause_activity (Token|1|5),(Component Name|3) -# Application process has been started -30014 am_proc_start (PID|1|5),(UID|1|5),(Process Name|3),(Type|3),(Component|3) -# An application process has been marked as bad -30015 am_proc_bad (UID|1|5),(Process Name|3) -# An application process that was bad is now marked as good -30016 am_proc_good (UID|1|5),(Process Name|3) -# Reporting to applications that memory is low -30017 am_low_memory (Num Processes|1|1) -# An activity is being destroyed: -30018 am_destroy_activity (Token|1|5),(Task ID|1|5),(Component Name|3) -# An activity has been relaunched, resumed, and is now in the foreground: -30019 am_relaunch_resume_activity (Token|1|5),(Task ID|1|5),(Component Name|3) -# An activity has been relaunched: -30020 am_relaunch_activity (Token|1|5),(Task ID|1|5),(Component Name|3) -# The activity's onPause has been called. -30021 am_on_paused_called (Component Name|3) -# The activity's onResume has been called. -30022 am_on_resume_called (Component Name|3) -# Kill a process to reclaim memory. -30023 am_kill_for_memory (PID|1|5),(Process Name|3),(OomAdj|1|5) -# Discard an undelivered serialized broadcast (timeout/ANR/crash) -30024 am_broadcast_discard_filter (Broadcast|1|5),(Action|3),(Receiver Number|1|1),(BroadcastFilter|1|5) -30025 am_broadcast_discard_app (Broadcast|1|5),(Action|3),(Receiver Number|1|1),(App|3) -# A service is being created -30030 am_create_service (Service Record|1|5),(Name|3),(Intent|3),(PID|1|5) -# A service is being destroyed -30031 am_destroy_service (Service Record|1|5),(Name|3),(PID|1|5) -# A process has crashed too many times, it is being cleared -30032 am_process_crashed_too_much (Name|3),(PID|1|5) -# An unknown process is trying to attach to the activity manager -30033 am_drop_process (PID|1|5) -# A service has crashed too many times, it is being stopped -30034 am_service_crashed_too_much (Crash Count|1|1),(Component Name|3),(PID|1|5) -# A service is going to be restarted after its process went away -30035 am_schedule_service_restart (Component Name|3),(Time|2|3) -# A client was waiting for a content provider, but its process was lost -30036 am_provider_lost_process (Package Name|3),(UID|1|5),(Name|3) - -# Out of memory for surfaces. -31000 wm_no_surface_memory (Window|3),(PID|1|5),(Operation|3) - -# Re-connecting to input method service because we haven't received its interface -32000 imf_force_reconnect_ime (IME|4),(Time Since Connect|2|3),(Showing|1|1) - -# dvm_gc_info: LIST (LONG, LONG, LONG) -# -# First LONG: -# -# [63] 1 -# [62-24] ASCII process identifier -# [23-12] GC time in ms -# [11- 0] Bytes freed -# -# Second LONG (aggregated heap info): -# -# [63-62] 10 -# [61-60] Reserved; must be zero -# [59-48] Objects freed -# [47-36] Actual size (current footprint) -# [35-24] Allowed size (current hard max) -# [23-12] Objects allocated -# [11- 0] Bytes allocated -# -# Third LONG (zygote heap info): -# -# [63-62] 11 -# [61-60] Reserved; must be zero -# [59-48] Soft limit -# [47-36] Actual size (current footprint) -# [35-24] Allowed size (current hard max) -# [23-12] Objects allocated -# [11- 0] Bytes allocated -# -# Fourth LONG: -# -# [63-48] Reserved; must be zero -# [47-36] dlmallocFootprint -# [35-24] mallinfo: total allocated space -# [23-12] External byte limit -# [11- 0] External bytes allocated -# -# See HeapDebug.c -# -20001 dvm_gc_info (custom|2),(custom|2),(custom|2),(custom|2) -20002 dvm_gc_madvise_info (total|1|2),(zygote|1|2) - -75000 sqlite_mem_alarm_current (current|1|2) -75001 sqlite_mem_alarm_max (max|1|2) -75002 sqlite_mem_alarm_alloc_attempt (attempts|1|4) -75003 sqlite_mem_released (Memory released|1|2) - -40000 checkin (Check in time|2|3) - -50000 menu_item_selected (Menu type where 0 is options and 1 is context|1|5),(Menu item title|3) -50001 menu_opened (Menu type where 0 is options and 1 is context|1|5) -# Connectivity state changed: -# [31-13] Reserved for future use -# [12- 9] Network subtype (for mobile network, as defined by TelephonyManager) -# [ 8- 3] Detailed state ordinal (as defined by NetworkInfo.DetailedState) -# [ 2- 0] Network type (as defined by ConnectivityManager) -50020 connectivity_state_changed (custom|1|5) - -# Wi-Fi network state changed: -# [31- 6] Reserved for future use -# [ 5- 0] Detailed state ordinal (as defined by NetworkInfo.DetailedState) -50021 wifi_network_state_changed (network_state|1|5) - -# Wi-Fi supplicant state changed: -# [31- 6] Reserved for future use -# [ 5- 0] Supplicant state ordinal (as defined by SupplicantState) -50022 wifi_supplicant_state_changed (supplicant_state|1|5) - -# Wi-Fi driver state changed: -# [31- 1] Reserved for future use -# [ 0- 0] Driver start (1) or stopped (0) -50023 wifi_driver_state_changed (driver_state|1|5) - -# Wi-Fi interface configuration state changed: -# [31- 1] Reserved for future use -# [ 0- 0] Interface configuration succeeded (1) or failed (0) -50024 wifi_interface_configuration_state_changed (IP_configuration|1|5) - -# Wi-Fi supplicant connection state changed: -# [31- 2] Reserved for future use -# [ 1- 0] Connected to supplicant (1) or disconnected from supplicant (0), -# or supplicant died (2) -50025 wifi_supplicant_connection_state_changed (connected|1|5) - -# PDP Context has a bad DNS address -50100 pdp_bad_dns_address (dns_address|3) - -# For data connection on PDP context, reached the data-out-without-data-in -# packet count that triggers a countdown to radio restart -50101 pdp_radio_reset_countdown_triggered (out_packet_count|1|1) - -# Radio restart - timed out with no incoming packets. -50102 pdp_radio_reset (out_packet_count|1|1) - -# PDP context reset - timed out with no incoming packets. -50103 pdp_context_reset (out_packet_count|1|1) - -# Reregister to data network - timed out with no incoming packets. -50104 pdp_reregister_network (out_packet_count|1|1) - -# PDP Setup failures -50105 pdp_setup_fail (cause|1|5), (cid|1|5), (network_type|1|5) - -# Call drops -50106 call_drop (cause|1|5), (cid|1|5), (network_type|1|5) - -# Data network registration failed after successful voice registration -50107 data_network_registration_fail (op_numeric|1|5), (cid|1|5) - -# Suspicious status of data connection while radio poweroff -50108 data_network_status_on_radio_off (dc_state|3), (enable|1|5) - -# PDP drop caused by network -50109 pdp_network_drop (cid|1|5), (network_type|1|5) - -# Do not change these names without updating tag in: -#//device/dalvik/libcore/luni/src/main/native/org_apache_harmony_luni_platform_OSNetworkSystem.c -51000 socket_stats (send|1|2),(recv|1|2),(ip|1|5),(port|1|5),(close|1|5) - -# db stats. 0 is query, 1 is write (may become more fine grained in the -# future) -52000 db_operation (name|3),(op_type|1|5),(time|2|3) - -# http request/response stats -52001 http_stats (useragent|3),(response|2|3),(processing|2|3),(tx|1|2),(rx|1|2) -60000 viewroot_draw (Draw time|1|3) -60001 viewroot_layout (Layout time|1|3) -60002 view_build_drawing_cache (View created drawing cache|1|5) -60003 view_use_drawing_cache (View drawn using bitmap cache|1|5) - -# 0 for screen off, 1 for screen on, 2 for key-guard done -70000 screen_toggled (screen_state|1|5) - -# browser stats for diary study -70101 browser_zoom_level_change (start level|1|5),(end level|1|5),(time|2|3) -70102 browser_double_tap_duration (duration|1|3),(time|2|3) \ No newline at end of file diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp deleted file mode 100644 index 3130a1cce7aa689e58ea5101b7e4030336ec78dd..0000000000000000000000000000000000000000 --- a/logcat/logcat.cpp +++ /dev/null @@ -1,568 +0,0 @@ -// Copyright 2006 The Android Open Source Project - -#include <cutils/logger.h> -#include <cutils/logd.h> -#include <cutils/sockets.h> -#include <cutils/logprint.h> -#include <cutils/event_tag_map.h> - -#include <stdio.h> -#include <stdlib.h> -#include <stdarg.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <time.h> -#include <errno.h> -#include <assert.h> -#include <ctype.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <arpa/inet.h> - -#define DEFAULT_LOG_ROTATE_SIZE_KBYTES 16 -#define DEFAULT_MAX_ROTATED_LOGS 4 - -static AndroidLogFormat * g_logformat; - -/* logd prefixes records with a length field */ -#define RECORD_LENGTH_FIELD_SIZE_BYTES sizeof(uint32_t) - -#define LOG_FILE_DIR "/dev/log/" - - -namespace android { - -/* Global Variables */ - -static const char * g_outputFileName = NULL; -static int g_logRotateSizeKBytes = 0; // 0 means "no log rotation" -static int g_maxRotatedLogs = DEFAULT_MAX_ROTATED_LOGS; // 0 means "unbounded" -static int g_outFD = -1; -static off_t g_outByteCount = 0; -static int g_isBinary = 0; -static int g_printBinary = 0; - -static EventTagMap* g_eventTagMap = NULL; - -static int openLogFile (const char *pathname) -{ - return open(g_outputFileName, O_WRONLY | O_APPEND | O_CREAT, S_IRUSR | S_IWUSR); -} - -static void rotateLogs() -{ - int err; - - // Can't rotate logs if we're not outputting to a file - if (g_outputFileName == NULL) { - return; - } - - close(g_outFD); - - for (int i = g_maxRotatedLogs ; i > 0 ; i--) { - char *file0, *file1; - - asprintf(&file1, "%s.%d", g_outputFileName, i); - - if (i - 1 == 0) { - asprintf(&file0, "%s", g_outputFileName); - } else { - asprintf(&file0, "%s.%d", g_outputFileName, i - 1); - } - - err = rename (file0, file1); - - if (err < 0 && errno != ENOENT) { - perror("while rotating log files"); - } - - free(file1); - free(file0); - } - - g_outFD = openLogFile (g_outputFileName); - - if (g_outFD < 0) { - perror ("couldn't open output file"); - exit(-1); - } - - g_outByteCount = 0; - -} - -void printBinary(struct logger_entry *buf) -{ - size_t size = sizeof(logger_entry) + buf->len; - int ret; - - do { - ret = write(g_outFD, buf, size); - } while (ret < 0 && errno == EINTR); -} - -static void processBuffer(struct logger_entry *buf) -{ - int bytesWritten; - int err; - AndroidLogEntry entry; - char binaryMsgBuf[1024]; - - if (g_isBinary) { - err = android_log_processBinaryLogBuffer(buf, &entry, g_eventTagMap, - binaryMsgBuf, sizeof(binaryMsgBuf)); - //printf(">>> pri=%d len=%d msg='%s'\n", - // entry.priority, entry.messageLen, entry.message); - } else { - err = android_log_processLogBuffer(buf, &entry); - } - if (err < 0) - goto error; - - bytesWritten = android_log_filterAndPrintLogLine( - g_logformat, g_outFD, &entry); - - if (bytesWritten < 0) { - perror("output error"); - exit(-1); - } - - g_outByteCount += bytesWritten; - - if (g_logRotateSizeKBytes > 0 - && (g_outByteCount / 1024) >= g_logRotateSizeKBytes - ) { - rotateLogs(); - } - -error: - //fprintf (stderr, "Error processing record\n"); - return; -} - -static void readLogLines(int logfd) -{ - while (1) { - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1] __attribute__((aligned(4))); - struct logger_entry *entry = (struct logger_entry *) buf; - int ret; - - ret = read(logfd, entry, LOGGER_ENTRY_MAX_LEN); - if (ret < 0) { - if (errno == EINTR) - continue; - if (errno == EAGAIN) - break; - perror("logcat read"); - exit(EXIT_FAILURE); - } - else if (!ret) { - fprintf(stderr, "read: Unexpected EOF!\n"); - exit(EXIT_FAILURE); - } - - /* NOTE: driver guarantees we read exactly one full entry */ - - entry->msg[entry->len] = '\0'; - - if (g_printBinary) { - printBinary(entry); - } else { - (void) processBuffer(entry); - } - } -} - -static int clearLog(int logfd) -{ - return ioctl(logfd, LOGGER_FLUSH_LOG); -} - -/* returns the total size of the log's ring buffer */ -static int getLogSize(int logfd) -{ - return ioctl(logfd, LOGGER_GET_LOG_BUF_SIZE); -} - -/* returns the readable size of the log's ring buffer (that is, amount of the log consumed) */ -static int getLogReadableSize(int logfd) -{ - return ioctl(logfd, LOGGER_GET_LOG_LEN); -} - -static void setupOutput() -{ - - if (g_outputFileName == NULL) { - g_outFD = STDOUT_FILENO; - - } else { - struct stat statbuf; - - g_outFD = openLogFile (g_outputFileName); - - if (g_outFD < 0) { - perror ("couldn't open output file"); - exit(-1); - } - - fstat(g_outFD, &statbuf); - - g_outByteCount = statbuf.st_size; - } -} - -static void show_help(const char *cmd) -{ - fprintf(stderr,"Usage: %s [options] [filterspecs]\n", cmd); - - fprintf(stderr, "options include:\n" - " -s Set default filter to silent.\n" - " Like specifying filterspec '*:s'\n" - " -f <filename> Log to file. Default to stdout\n" - " -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n" - " -n <count> Sets max number of rotated logs to <count>, default 4\n" - " -v <format> Sets the log print format, where <format> is one of:\n\n" - " brief process tag thread raw time threadtime long\n\n" - " -c clear (flush) the entire log and exit\n" - " -d dump the log and then exit (don't block)\n" - " -g get the size of the log's ring buffer and exit\n" - " -b <buffer> request alternate ring buffer\n" - " ('main' (default), 'radio', 'events')\n" - " -B output the log in binary"); - - - fprintf(stderr,"\nfilterspecs are a series of \n" - " <tag>[:priority]\n\n" - "where <tag> is a log component tag (or * for all) and priority is:\n" - " V Verbose\n" - " D Debug\n" - " I Info\n" - " W Warn\n" - " E Error\n" - " F Fatal\n" - " S Silent (supress all output)\n" - "\n'*' means '*:d' and <tag> by itself means <tag>:v\n" - "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n" - "If no filterspec is found, filter defaults to '*:I'\n" - "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n" - "or defaults to \"brief\"\n\n"); - - - -} - - -} /* namespace android */ - -static int setLogFormat(const char * formatString) -{ - static AndroidLogPrintFormat format; - - format = android_log_formatFromString(formatString); - - if (format == FORMAT_OFF) { - // FORMAT_OFF means invalid string - return -1; - } - - android_log_setPrintFormat(g_logformat, format); - - return 0; -} - -extern "C" void logprint_run_tests(void); - -int main (int argc, char **argv) -{ - int logfd; - int err; - int hasSetLogFormat = 0; - int clearLog = 0; - int getLogSize = 0; - int mode = O_RDONLY; - char *log_device = strdup("/dev/"LOGGER_LOG_MAIN); - const char *forceFilters = NULL; - - g_logformat = android_log_format_new(); - - if (argc == 2 && 0 == strcmp(argv[1], "--test")) { - logprint_run_tests(); - exit(0); - } - - if (argc == 2 && 0 == strcmp(argv[1], "--help")) { - android::show_help(argv[0]); - exit(0); - } - - for (;;) { - int ret; - - ret = getopt(argc, argv, "cdgsQf:r::n:v:b:B"); - - if (ret < 0) { - break; - } - - switch(ret) { - case 's': - // default to all silent - android_log_addFilterRule(g_logformat, "*:s"); - break; - - case 'c': - clearLog = 1; - mode = O_WRONLY; - break; - - case 'd': - mode |= O_NONBLOCK; - break; - - case 'g': - getLogSize = 1; - break; - - case 'b': - free(log_device); - log_device = - (char*) malloc(strlen(LOG_FILE_DIR) + strlen(optarg) + 1); - strcpy(log_device, LOG_FILE_DIR); - strcat(log_device, optarg); - - android::g_isBinary = (strcmp(optarg, "events") == 0); - break; - - case 'B': - android::g_printBinary = 1; - break; - - case 'f': - // redirect output to a file - - android::g_outputFileName = optarg; - - break; - - case 'r': - if (optarg == NULL) { - android::g_logRotateSizeKBytes - = DEFAULT_LOG_ROTATE_SIZE_KBYTES; - } else { - long logRotateSize; - char *lastDigit; - - if (!isdigit(optarg[0])) { - fprintf(stderr,"Invalid parameter to -r\n"); - android::show_help(argv[0]); - exit(-1); - } - android::g_logRotateSizeKBytes = atoi(optarg); - } - break; - - case 'n': - if (!isdigit(optarg[0])) { - fprintf(stderr,"Invalid parameter to -r\n"); - android::show_help(argv[0]); - exit(-1); - } - - android::g_maxRotatedLogs = atoi(optarg); - break; - - case 'v': - err = setLogFormat (optarg); - if (err < 0) { - fprintf(stderr,"Invalid parameter to -v\n"); - android::show_help(argv[0]); - exit(-1); - } - - hasSetLogFormat = 1; - break; - - case 'Q': - /* this is a *hidden* option used to start a version of logcat */ - /* in an emulated device only. it basically looks for androidboot.logcat= */ - /* on the kernel command line. If something is found, it extracts a log filter */ - /* and uses it to run the program. If nothing is found, the program should */ - /* quit immediately */ -#define KERNEL_OPTION "androidboot.logcat=" -#define CONSOLE_OPTION "androidboot.console=" - { - int fd; - char* logcat; - char* console; - int force_exit = 1; - static char cmdline[1024]; - - fd = open("/proc/cmdline", O_RDONLY); - if (fd >= 0) { - int n = read(fd, cmdline, sizeof(cmdline)-1 ); - if (n < 0) n = 0; - cmdline[n] = 0; - close(fd); - } else { - cmdline[0] = 0; - } - - logcat = strstr( cmdline, KERNEL_OPTION ); - console = strstr( cmdline, CONSOLE_OPTION ); - if (logcat != NULL) { - char* p = logcat + sizeof(KERNEL_OPTION)-1;; - char* q = strpbrk( p, " \t\n\r" );; - - if (q != NULL) - *q = 0; - - forceFilters = p; - force_exit = 0; - } - /* if nothing found or invalid filters, exit quietly */ - if (force_exit) - exit(0); - - /* redirect our output to the emulator console */ - if (console) { - char* p = console + sizeof(CONSOLE_OPTION)-1; - char* q = strpbrk( p, " \t\n\r" ); - char devname[64]; - int len; - - if (q != NULL) { - len = q - p; - } else - len = strlen(p); - - len = snprintf( devname, sizeof(devname), "/dev/%.*s", len, p ); - fprintf(stderr, "logcat using %s (%d)\n", devname, len); - if (len < (int)sizeof(devname)) { - fd = open( devname, O_WRONLY ); - if (fd >= 0) { - dup2(fd, 1); - dup2(fd, 2); - close(fd); - } - } - } - } - break; - - default: - fprintf(stderr,"Unrecognized Option\n"); - android::show_help(argv[0]); - exit(-1); - break; - } - } - - if (android::g_logRotateSizeKBytes != 0 - && android::g_outputFileName == NULL - ) { - fprintf(stderr,"-r requires -f as well\n"); - android::show_help(argv[0]); - exit(-1); - } - - android::setupOutput(); - - if (hasSetLogFormat == 0) { - const char* logFormat = getenv("ANDROID_PRINTF_LOG"); - - if (logFormat != NULL) { - err = setLogFormat(logFormat); - - if (err < 0) { - fprintf(stderr, "invalid format in ANDROID_PRINTF_LOG '%s'\n", - logFormat); - } - } - } - - if (forceFilters) { - err = android_log_addFilterString(g_logformat, forceFilters); - if (err < 0) { - fprintf (stderr, "Invalid filter expression in -logcat option\n"); - exit(0); - } - } else if (argc == optind) { - // Add from environment variable - char *env_tags_orig = getenv("ANDROID_LOG_TAGS"); - - if (env_tags_orig != NULL) { - err = android_log_addFilterString(g_logformat, env_tags_orig); - - if (err < 0) { - fprintf(stderr, "Invalid filter expression in" - " ANDROID_LOG_TAGS\n"); - android::show_help(argv[0]); - exit(-1); - } - } - } else { - // Add from commandline - for (int i = optind ; i < argc ; i++) { - err = android_log_addFilterString(g_logformat, argv[i]); - - if (err < 0) { - fprintf (stderr, "Invalid filter expression '%s'\n", argv[i]); - android::show_help(argv[0]); - exit(-1); - } - } - } - - logfd = open(log_device, mode); - if (logfd < 0) { - fprintf(stderr, "Unable to open log device '%s': %s\n", - log_device, strerror(errno)); - exit(EXIT_FAILURE); - } - - if (clearLog) { - int ret; - ret = android::clearLog(logfd); - if (ret) { - perror("ioctl"); - exit(EXIT_FAILURE); - } - return 0; - } - - if (getLogSize) { - int size, readable; - - size = android::getLogSize(logfd); - if (size < 0) { - perror("ioctl"); - exit(EXIT_FAILURE); - } - - readable = android::getLogReadableSize(logfd); - if (readable < 0) { - perror("ioctl"); - exit(EXIT_FAILURE); - } - - printf("ring buffer is %dKb (%dKb consumed), " - "max entry is %db, max payload is %db\n", - size / 1024, readable / 1024, - (int) LOGGER_ENTRY_MAX_LEN, (int) LOGGER_ENTRY_MAX_PAYLOAD); - return 0; - } - - //LOG_EVENT_INT(10, 12345); - //LOG_EVENT_LONG(11, 0x1122334455667788LL); - //LOG_EVENT_STRING(0, "whassup, doc?"); - - if (android::g_isBinary) - android::g_eventTagMap = android_openEventTagMap(EVENT_TAG_MAP_FILE); - - android::readLogLines(logfd); - - return 0; -} diff --git a/logwrapper/Android.mk b/logwrapper/Android.mk deleted file mode 100644 index 5fd635676ee267bcd00cd240cab0802ac750b0ab..0000000000000000000000000000000000000000 --- a/logwrapper/Android.mk +++ /dev/null @@ -1,7 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES:= logwrapper.c -LOCAL_MODULE := logwrapper -LOCAL_STATIC_LIBRARIES := liblog -include $(BUILD_EXECUTABLE) diff --git a/logwrapper/logwrapper.c b/logwrapper/logwrapper.c deleted file mode 100644 index f00bfbf3d0bff76fea2544aa6919e4e0323b979f..0000000000000000000000000000000000000000 --- a/logwrapper/logwrapper.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> - -#include "private/android_filesystem_config.h" -#include "cutils/log.h" - -void fatal(const char *msg) { - fprintf(stderr, msg); - LOG(LOG_ERROR, "logwrapper", msg); - exit(-1); -} - -void usage() { - fatal( - "Usage: logwrapper [-x] BINARY [ARGS ...]\n" - "\n" - "Forks and executes BINARY ARGS, redirecting stdout and stderr to\n" - "the Android logging system. Tag is set to BINARY, priority is\n" - "always LOG_INFO.\n" - "\n" - "-x: Causes logwrapper to SIGSEGV when BINARY terminates\n" - " fault address is set to the status of wait()\n"); -} - -void parent(const char *tag, int seg_fault_on_exit, int parent_read) { - int status; - char buffer[4096]; - - int a = 0; // start index of unprocessed data - int b = 0; // end index of unprocessed data - int sz; - while ((sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b)) > 0) { - - sz += b; - // Log one line at a time - for (b = 0; b < sz; b++) { - if (buffer[b] == '\r') { - buffer[b] = '\0'; - } else if (buffer[b] == '\n') { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - a = b + 1; - } - } - - if (a == 0 && b == sizeof(buffer) - 1) { - // buffer is full, flush - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - b = 0; - } else if (a != b) { - // Keep left-overs - b -= a; - memmove(buffer, &buffer[a], b); - a = 0; - } else { - a = 0; - b = 0; - } - - } - // Flush remaining data - if (a != b) { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - } - status = 0xAAAA; - if (wait(&status) != -1) { // Wait for child - if (WIFEXITED(status)) - LOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", tag, - WEXITSTATUS(status)); - else if (WIFSIGNALED(status)) - LOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", tag, - WTERMSIG(status)); - else if (WIFSTOPPED(status)) - LOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", tag, - WSTOPSIG(status)); - } else - LOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag, - strerror(errno), errno); - if (seg_fault_on_exit) - *(int *)status = 0; // causes SIGSEGV with fault_address = status -} - -void child(int argc, char* argv[]) { - // create null terminated argv_child array - char* argv_child[argc + 1]; - memcpy(argv_child, argv, argc * sizeof(char *)); - argv_child[argc] = NULL; - - if (execvp(argv_child[0], argv_child)) { - LOG(LOG_ERROR, "logwrapper", - "executing %s failed: %s\n", argv_child[0], strerror(errno)); - exit(-1); - } -} - -int main(int argc, char* argv[]) { - pid_t pid; - int seg_fault_on_exit = 0; - - int parent_ptty; - int child_ptty; - char *child_devname = NULL; - - if (argc < 2) { - usage(); - } - - if (strncmp(argv[1], "-d", 2) == 0) { - seg_fault_on_exit = 1; - argc--; - argv++; - } - - if (argc < 2) { - usage(); - } - - /* Use ptty instead of socketpair so that STDOUT is not buffered */ - parent_ptty = open("/dev/ptmx", O_RDWR); - if (parent_ptty < 0) { - fatal("Cannot create parent ptty\n"); - } - - if (grantpt(parent_ptty) || unlockpt(parent_ptty) || - ((child_devname = (char*)ptsname(parent_ptty)) == 0)) { - fatal("Problem with /dev/ptmx\n"); - } - - pid = fork(); - if (pid < 0) { - fatal("Failed to fork\n"); - } else if (pid == 0) { - child_ptty = open(child_devname, O_RDWR); - if (child_ptty < 0) { - fatal("Problem with child ptty\n"); - } - - // redirect stdout and stderr - close(parent_ptty); - dup2(child_ptty, 1); - dup2(child_ptty, 2); - close(child_ptty); - - child(argc - 1, &argv[1]); - - } else { - // switch user and group to "log" - // this may fail if we are not root, - // but in that case switching user/group is unnecessary - setgid(AID_LOG); - setuid(AID_LOG); - - parent(argv[1], seg_fault_on_exit, parent_ptty); - } - - return 0; -} diff --git a/mkbootimg/Android.mk b/mkbootimg/Android.mk deleted file mode 100644 index 18f0ff3060f383f9dc03f4c607861cdcf64f4f04..0000000000000000000000000000000000000000 --- a/mkbootimg/Android.mk +++ /dev/null @@ -1,12 +0,0 @@ - -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := mkbootimg.c -LOCAL_STATIC_LIBRARIES := libmincrypt - -LOCAL_MODULE := mkbootimg - -include $(BUILD_HOST_EXECUTABLE) - -$(call dist-for-goals,droid,$(LOCAL_BUILT_MODULE)) diff --git a/mkbootimg/bootimg.h b/mkbootimg/bootimg.h deleted file mode 100644 index 242ab35db82be002005dbd3ce51e34dd7404d8e0..0000000000000000000000000000000000000000 --- a/mkbootimg/bootimg.h +++ /dev/null @@ -1,97 +0,0 @@ -/* tools/mkbootimg/bootimg.h -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#ifndef _BOOT_IMAGE_H_ -#define _BOOT_IMAGE_H_ - -typedef struct boot_img_hdr boot_img_hdr; - -#define BOOT_MAGIC "ANDROID!" -#define BOOT_MAGIC_SIZE 8 -#define BOOT_NAME_SIZE 16 -#define BOOT_ARGS_SIZE 512 - -struct boot_img_hdr -{ - unsigned char magic[BOOT_MAGIC_SIZE]; - - unsigned kernel_size; /* size in bytes */ - unsigned kernel_addr; /* physical load addr */ - - unsigned ramdisk_size; /* size in bytes */ - unsigned ramdisk_addr; /* physical load addr */ - - unsigned second_size; /* size in bytes */ - unsigned second_addr; /* physical load addr */ - - unsigned tags_addr; /* physical addr for kernel tags */ - unsigned page_size; /* flash page size we assume */ - unsigned unused[2]; /* future expansion: should be 0 */ - - unsigned char name[BOOT_NAME_SIZE]; /* asciiz product name */ - - unsigned char cmdline[BOOT_ARGS_SIZE]; - - unsigned id[8]; /* timestamp / checksum / sha1 / etc */ -}; - -/* -** +-----------------+ -** | boot header | 1 page -** +-----------------+ -** | kernel | n pages -** +-----------------+ -** | ramdisk | m pages -** +-----------------+ -** | second stage | o pages -** +-----------------+ -** -** n = (kernel_size + page_size - 1) / page_size -** m = (ramdisk_size + page_size - 1) / page_size -** o = (second_size + page_size - 1) / page_size -** -** 0. all entities are page_size aligned in flash -** 1. kernel and ramdisk are required (size != 0) -** 2. second is optional (second_size == 0 -> no second) -** 3. load each element (kernel, ramdisk, second) at -** the specified physical address (kernel_addr, etc) -** 4. prepare tags at tag_addr. kernel_args[] is -** appended to the kernel commandline in the tags. -** 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr -** 6. if second_size != 0: jump to second_addr -** else: jump to kernel_addr -*/ - -#if 0 -typedef struct ptentry ptentry; - -struct ptentry { - char name[16]; /* asciiz partition name */ - unsigned start; /* starting block number */ - unsigned length; /* length in blocks */ - unsigned flags; /* set to zero */ -}; - -/* MSM Partition Table ATAG -** -** length: 2 + 7 * n -** atag: 0x4d534d70 -** <ptentry> x n -*/ -#endif - -#endif diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c deleted file mode 100644 index d803cf66d0a3a352c68f794ea93f00f191e91b9b..0000000000000000000000000000000000000000 --- a/mkbootimg/mkbootimg.c +++ /dev/null @@ -1,251 +0,0 @@ -/* tools/mkbootimg/mkbootimg.c -** -** Copyright 2007, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> - -#include "mincrypt/sha.h" -#include "bootimg.h" - -static void *load_file(const char *fn, unsigned *_sz) -{ - char *data; - int sz; - int fd; - - data = 0; - fd = open(fn, O_RDONLY); - if(fd < 0) return 0; - - sz = lseek(fd, 0, SEEK_END); - if(sz < 0) goto oops; - - if(lseek(fd, 0, SEEK_SET) != 0) goto oops; - - data = (char*) malloc(sz); - if(data == 0) goto oops; - - if(read(fd, data, sz) != sz) goto oops; - close(fd); - - if(_sz) *_sz = sz; - return data; - -oops: - close(fd); - if(data != 0) free(data); - return 0; -} - -int usage(void) -{ - fprintf(stderr,"usage: mkbootimg\n" - " --kernel <filename>\n" - " --ramdisk <filename>\n" - " [ --second <2ndbootloader-filename> ]\n" - " [ --cmdline <kernel-commandline> ]\n" - " [ --board <boardname> ]\n" - " -o|--output <filename>\n" - ); - return 1; -} - - - -static unsigned char padding[2048] = { 0, }; - -int write_padding(int fd, unsigned pagesize, unsigned itemsize) -{ - unsigned pagemask = pagesize - 1; - unsigned count; - - if((itemsize & pagemask) == 0) { - return 0; - } - - count = pagesize - (itemsize & pagemask); - - if(write(fd, padding, count) != count) { - return -1; - } else { - return 0; - } -} - -int main(int argc, char **argv) -{ - boot_img_hdr hdr; - - char *kernel_fn = 0; - void *kernel_data = 0; - char *ramdisk_fn = 0; - void *ramdisk_data = 0; - char *second_fn = 0; - void *second_data = 0; - char *cmdline = ""; - char *bootimg = 0; - char *board = ""; - unsigned pagesize = 2048; - unsigned saddr = 0; - int fd; - SHA_CTX ctx; - uint8_t* sha; - - argc--; - argv++; - - memset(&hdr, 0, sizeof(hdr)); - - while(argc > 0){ - char *arg = argv[0]; - char *val = argv[1]; - if(argc < 2) { - return usage(); - } - argc -= 2; - argv += 2; - if(!strcmp(arg, "--output") || !strcmp(arg, "-o")) { - bootimg = val; - } else if(!strcmp(arg, "--kernel")) { - kernel_fn = val; - } else if(!strcmp(arg, "--ramdisk")) { - ramdisk_fn = val; - } else if(!strcmp(arg, "--second")) { - second_fn = val; - } else if(!strcmp(arg, "--cmdline")) { - cmdline = val; - } else if(!strcmp(arg, "--saddr")) { - saddr = strtoul(val, 0, 16); - } else if(!strcmp(arg, "--board")) { - board = val; - } else { - return usage(); - } - } - - if(bootimg == 0) { - fprintf(stderr,"error: no output filename specified\n"); - return usage(); - } - - if(kernel_fn == 0) { - fprintf(stderr,"error: no kernel image specified\n"); - return usage(); - } - - if(ramdisk_fn == 0) { - fprintf(stderr,"error: no ramdisk image specified\n"); - return usage(); - } - - if(strlen(board) >= BOOT_NAME_SIZE) { - fprintf(stderr,"error: board name too large\n"); - return usage(); - } - - strcpy(hdr.name, board); - - hdr.kernel_addr = 0x10008000; - hdr.ramdisk_addr = 0x11000000; - if(saddr) { - hdr.second_addr = 0x00300000; - } else { - hdr.second_addr = 0x10F00000; - } - hdr.tags_addr = 0x10000100; - hdr.page_size = pagesize; - - memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); - - if(strlen(cmdline) > (BOOT_ARGS_SIZE - 1)) { - fprintf(stderr,"error: kernel commandline too large\n"); - return 1; - } - strcpy((char*)hdr.cmdline, cmdline); - - kernel_data = load_file(kernel_fn, &hdr.kernel_size); - if(kernel_data == 0) { - fprintf(stderr,"error: could not load kernel '%s'\n", kernel_fn); - return 1; - } - - if(!strcmp(ramdisk_fn,"NONE")) { - ramdisk_data = 0; - hdr.ramdisk_size = 0; - } else { - ramdisk_data = load_file(ramdisk_fn, &hdr.ramdisk_size); - if(ramdisk_data == 0) { - fprintf(stderr,"error: could not load ramdisk '%s'\n", ramdisk_fn); - return 1; - } - } - - if(second_fn) { - second_data = load_file(second_fn, &hdr.second_size); - if(second_data == 0) { - fprintf(stderr,"error: could not load secondstage '%s'\n", second_fn); - return 1; - } - } - - /* put a hash of the contents in the header so boot images can be - * differentiated based on their first 2k. - */ - SHA_init(&ctx); - SHA_update(&ctx, kernel_data, hdr.kernel_size); - SHA_update(&ctx, &hdr.kernel_size, sizeof(hdr.kernel_size)); - SHA_update(&ctx, ramdisk_data, hdr.ramdisk_size); - SHA_update(&ctx, &hdr.ramdisk_size, sizeof(hdr.ramdisk_size)); - SHA_update(&ctx, second_data, hdr.second_size); - SHA_update(&ctx, &hdr.second_size, sizeof(hdr.second_size)); - sha = SHA_final(&ctx); - memcpy(hdr.id, sha, - SHA_DIGEST_SIZE > sizeof(hdr.id) ? sizeof(hdr.id) : SHA_DIGEST_SIZE); - - fd = open(bootimg, O_CREAT | O_TRUNC | O_WRONLY, 0644); - if(fd < 0) { - fprintf(stderr,"error: could not create '%s'\n", bootimg); - return 1; - } - - if(write(fd, &hdr, sizeof(hdr)) != sizeof(hdr)) goto fail; - if(write_padding(fd, pagesize, sizeof(hdr))) goto fail; - - if(write(fd, kernel_data, hdr.kernel_size) != hdr.kernel_size) goto fail; - if(write_padding(fd, pagesize, hdr.kernel_size)) goto fail; - - if(write(fd, ramdisk_data, hdr.ramdisk_size) != hdr.ramdisk_size) goto fail; - if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; - - if(second_data) { - if(write(fd, second_data, hdr.second_size) != hdr.second_size) goto fail; - if(write_padding(fd, pagesize, hdr.ramdisk_size)) goto fail; - } - - return 0; - -fail: - unlink(bootimg); - close(fd); - fprintf(stderr,"error: failed writing '%s': %s\n", bootimg, - strerror(errno)); - return 1; -} diff --git a/mountd/ASEC.c b/mountd/ASEC.c deleted file mode 100644 index a6aab9c52556ff39c4cbdc2bb401463004e9592b..0000000000000000000000000000000000000000 --- a/mountd/ASEC.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** Android Secure External Cache -*/ - -#include "mountd.h" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <dirent.h> -#include <ctype.h> -#include <pwd.h> -#include <stdlib.h> -#include <poll.h> -#include <errno.h> - -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/stat.h> - -#include <linux/dm-ioctl.h> -#include <linux/loop.h> - -#include <cutils/properties.h> -#include <cutils/misc.h> - -#include "ASEC.h" - -//#define MODULE_FAILURE_IS_FATAL - -extern int init_module(void *, unsigned long, const char *); -extern int delete_module(const char *, unsigned int); - -struct asec_context -{ - char *name; // Device mapper volume name - char *srcPath; // Path to the source (original) mount - char *backingFile; // Name of the image file - unsigned int sectors; // Number of sectors - char *dstPath; // Destination mount point - char *crypt; // Crypt options - - boolean needs_format; - boolean started; - int cacheFd; - int lo_num; - int dm_num; - unsigned char key[16]; -}; - -static const char *MODULES[] = { "dm_mod", "crypto", "crypto_algapi", "crypto_blkcipher", - "cryptomgr", "dm_crypt", "jbd", - "twofish_common", "twofish", "cbc", - "mbcache", "ext3", - NULL }; -static const char KEY_PATH[] = "/data/system/asec.key"; -static const char MODULE_PATH[] = "/system/lib/modules"; -static const char MKE2FS_PATH[] = "/system/bin/mke2fs"; -static const char E2FSCK_PATH[] = "/system/bin/e2fsck"; - -boolean AsecIsStarted(void *Handle) -{ - struct asec_context *ctx = (struct asec_context *) Handle; - - return ctx->started; -} - -const char *AsecMountPoint(void *Handle) -{ - struct asec_context *ctx = (struct asec_context *) Handle; - - return ctx->dstPath; -} - -static boolean AsecIsEnabled() -{ - char value[PROPERTY_VALUE_MAX]; - int enabled; - - property_get(ASEC_ENABLED, value, "0"); - - if (atoi(value) == 1) - return true; - return false; -} - -void *AsecInit(const char *Name, const char *SrcPath, const char *BackingFile, - const char *Size, const char *DstPath, const char *Crypt) -{ - struct asec_context *ctx; - - if (!AsecIsEnabled()) - return NULL; - - LOG_ASEC("AsecInit(%s, %s, %s, %s, %s, %s):\n", - Name, SrcPath, BackingFile, Size, DstPath, Crypt); - - if (!Name || !SrcPath || !BackingFile || !Size || !DstPath || !Crypt) { - LOG_ERROR("AsecInit(): Invalid arguments\n"); - return NULL; - } - - if (!(ctx = malloc(sizeof(struct asec_context)))) { - LOG_ERROR("AsecInit(): Out of memory\n"); - return NULL; - } - - memset(ctx, 0, sizeof(struct asec_context)); - ctx->name = strdup(Name); - ctx->srcPath = strdup(SrcPath); - ctx->backingFile = strdup(BackingFile); - ctx->sectors = atoi(Size); - ctx->dstPath = strdup(DstPath); - ctx->crypt = strdup(Crypt); - return ctx; -} - -void AsecDeinit(void *Handle) -{ - struct asec_context *ctx = (struct asec_context *) Handle; - - free(ctx->name); - free(ctx->srcPath); - free(ctx->backingFile); - free(ctx->dstPath); - free(ctx->crypt); - - free(ctx); -} - -static int AsecLoadModules() -{ - int i; - - for (i = 0; MODULES[i] != NULL; i++) { - const char *moduleName = MODULES[i]; - char moduleFile[255]; - int rc = 0; - void *module; - unsigned int size; - - sprintf(moduleFile, "%s/%s.ko", MODULE_PATH, moduleName); - module = load_file(moduleFile, &size); - if (!module) { - LOG_ERROR("Failed to load module %s (%d)\n", moduleFile, errno); - return -1; - } - - rc = init_module(module, size, ""); - free(module); - if (rc && errno != EEXIST) { - LOG_ERROR("Failed to init module %s (%d)\n", moduleFile, errno); - return -errno; - } - } - return 0; -} - -static int AsecUnloadModules() -{ - int i, j, rc; - - for (i = 0; MODULES[i] != NULL; i++); - - for (j = (i - 1); j >= 0; j--) { - const char *moduleName = MODULES[j]; - int maxretry = 10; - while(maxretry-- > 0) { - rc = delete_module(moduleName, O_NONBLOCK | O_EXCL); - if (rc < 0 && errno == EAGAIN) - usleep(500000); - else - break; - } - if (rc != 0) { - LOG_ERROR("Failed to unload module %s\n", moduleName); - return -errno; - } - } - return 0; -} - -static int AsecGenerateKey(struct asec_context *ctx) -{ - LOG_ASEC("AsecGenerateKey():\n"); - - memset((void *) ctx->key, 0x69, sizeof(ctx->key)); - return 0; -} - -static int AsecLoadGenerateKey(struct asec_context *ctx) -{ - int fd; - int rc = 0; - - if ((fd = open(KEY_PATH, O_RDWR | O_CREAT, 0600)) < 0) { - LOG_ERROR("Error opening / creating keyfile (%d)\n", errno); - return -errno; - } - - if (read(fd, ctx->key, sizeof(ctx->key)) != sizeof(ctx->key)) { - LOG_ASEC("Generating key\n"); - if ((rc = AsecGenerateKey(ctx)) < 0) { - LOG_ERROR("Error generating key (%d)\n", rc); - goto out; - } - if (write(fd, ctx->key, sizeof(ctx->key)) != sizeof(ctx->key)) { - LOG_ERROR("Error writing keyfile (%d)\n", errno); - rc = -1; - goto out; - } - } - - out: - close (fd); - return rc; -} - -static int AsecFormatFilesystem(struct asec_context *ctx) -{ - char cmdline[255]; - int rc; - - sprintf(cmdline, - "%s -b 4096 -m 1 -j -L \"%s\" /dev/block/dm-%d", - MKE2FS_PATH, ctx->name, ctx->dm_num); - - LOG_ASEC("Formatting filesystem (%s)\n", cmdline); - // XXX: PROTECT FROM VIKING KILLER - if ((rc = system(cmdline)) < 0) { - LOG_ERROR("Error executing format command (%d)\n", errno); - return -errno; - } - - rc = WEXITSTATUS(rc); - - if (!rc) { - LOG_ASEC("Format completed\n"); - } else { - LOG_ASEC("Format failed (%d)\n", rc); - } - - return rc; -} - -static int AsecCheckFilesystem(struct asec_context *ctx) -{ - char cmdline[255]; - int rc; - - sprintf(cmdline, "%s -p /dev/block/dm-%d", E2FSCK_PATH, ctx->dm_num); - - LOG_ASEC("Checking filesystem (%s)\n", cmdline); - // XXX: PROTECT FROM VIKING KILLER - if ((rc = system(cmdline)) < 0) { - LOG_ERROR("Error executing check command (%d)\n", errno); - return -errno; - } - - rc = WEXITSTATUS(rc); - - if (rc == 0) { - LOG_ASEC("ASEC volume '%s' had no errors\n", ctx->name); - } else if (rc == 1) { - LOG_ASEC("ASEC volume '%s' had corrected errors\n", ctx->name); - rc = 0; - } else if (rc == 2) { - LOG_ERROR("ASEC volume '%s' had corrected errors (system should be rebooted)\n", ctx->name); - } else if (rc == 4) { - LOG_ERROR("ASEC volume '%s' had uncorrectable errors\n", ctx->name); - } else if (rc == 8) { - LOG_ERROR("Operational error while checking volume '%s'\n", ctx->name); - } else { - LOG_ERROR("Unknown e2fsck exit code (%d)\n", rc); - } - return rc; -} - -static int AsecOpenCreateCache(struct asec_context *ctx) -{ - char filepath[255]; - - sprintf(filepath, "%s/%s", ctx->srcPath, ctx->backingFile); - - if ((ctx->cacheFd = open(filepath, O_RDWR)) < 0) { - if (errno == ENOENT) { - int rc = 0; - - LOG_ASEC("Creating cache file (%u sectors)\n", ctx->sectors); - if ((ctx->cacheFd = creat(filepath, 0600)) < 0) { - LOG_ERROR("Error creating cache (%d)\n", errno); - return -errno; - } - if (ftruncate(ctx->cacheFd, ctx->sectors * 512) < 0) { - LOG_ERROR("Error truncating cache (%d)\n", errno); - close(ctx->cacheFd); - unlink(filepath); - return -errno; - } - LOG_ASEC("Cache created (%u sectors) \n", ctx->sectors); - close(ctx->cacheFd); // creat() is WRONLY - - if ((ctx->cacheFd = open(filepath, O_RDWR)) < 0) { - LOG_ERROR("Error opening cache file (%d)\n", errno); - close(ctx->cacheFd); - unlink(filepath); - return -errno; - } - - ctx->needs_format = 1; - } else - return -errno; - } else { - struct stat stat_buf; - - if (fstat(ctx->cacheFd, &stat_buf) < 0) { - LOG_ERROR("Failed to fstat cache (%d)\n", errno); - close(ctx->cacheFd); - return -errno; - } - if (stat_buf.st_size != ctx->sectors * 512) { - LOG_ERROR("Cache size %lld != configured size %u\n", - stat_buf.st_size, ctx->sectors * 512); - } - - // XXX: Verify volume label matches ctx->name - } - - return 0; -} - -static void AsecCloseCache(struct asec_context *ctx) -{ - close(ctx->cacheFd); -} - -static void *_align(void *ptr, unsigned int a) -{ - register unsigned long agn = --a; - - return (void *) (((unsigned long) ptr + agn) & ~agn); -} - -static struct dm_ioctl *_dm_ioctl_setup(struct asec_context *ctx, int flags) -{ - void *buffer; - void *p; - const size_t min_size = 16 * 1024; - size_t len = sizeof(struct dm_ioctl); - struct dm_ioctl *io; - struct dm_target_spec *tgt; - int i; - char params[1024]; - char key[80]; - - key[0] = '\0'; - - for (i = 0; i < (int) sizeof(ctx->key); i++) { - char tmp[8]; - - sprintf(tmp, "%02x", ctx->key[i]); - strcat(key, tmp); - } - - // XXX: Handle ctx->crypt - sprintf(params, "twofish %s 0 /dev/block/loop%d 0", key, ctx->lo_num); - - if (len < min_size) - len = min_size; - - if (!(buffer = malloc(len))) { - LOG_ERROR("Unable to allocate memory\n"); - return NULL; - } - - memset(buffer, 0, len); - io = buffer; - tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - - io->data_size = len; - io->data_start = sizeof(struct dm_ioctl); - - io->flags = flags; - io->dev = 0; - - io->target_count = 1; - io->event_nr = 1; - strncpy(io->name, ctx->name, sizeof(io->name)); - - tgt->status = 0; - tgt->sector_start = 0; - tgt->length = ctx->sectors; - strncpy(tgt->target_type, "crypt", sizeof(tgt->target_type)); - - p = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - strcpy((char *) p, params); - p+= strlen(params) + 1; - - p = _align(p, 8); - tgt->next = p - buffer; - - return io; -} - -static int FindNextAvailableDm() -{ - int i; - - for (i = 0; i < 8; i++) { - char path[255]; - sprintf(path, "/dev/block/dm-%d", i); - if ((access(path, F_OK) < 0) && (errno == ENOENT)) - return i; - } - - LOG_ERROR("Out of device mapper numbers\n"); - return -1; -} - -static int AsecCreateDeviceMapping(struct asec_context *ctx) -{ - struct dm_ioctl *io; - int dmFd; - int rc = 0; - - ctx->dm_num = FindNextAvailableDm(); - - if ((dmFd = open("/dev/device-mapper", O_RDWR)) < 0) { - LOG_ERROR("Error opening device mapper (%d)\n", errno); - return -errno; - } - - if (!(io = _dm_ioctl_setup(ctx, 0))) { - LOG_ERROR("Unable to setup ioctl (out of memory)\n"); - close(dmFd); - return -ENOMEM; - } - - if ((rc = ioctl(dmFd, DM_DEV_CREATE, io)) < 0) { - LOG_ERROR("device-mapper create ioctl failed (%d)\n", errno); - rc = -errno; - goto out_free; - } - - free(io); - - if (!(io = _dm_ioctl_setup(ctx, DM_STATUS_TABLE_FLAG))) { - LOG_ERROR("Unable to setup ioctl (out of memory)\n"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(dmFd, DM_TABLE_LOAD, io)) < 0) { - LOG_ERROR("device-mapper load ioctl failed (%d)\n", errno); - rc = -errno; - goto out_free; - } - - free(io); - - if (!(io = _dm_ioctl_setup(ctx, 0))) { - LOG_ERROR("Unable to setup ioctl (out of memory)\n"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(dmFd, DM_DEV_SUSPEND, io)) < 0) { - LOG_ERROR("device-mapper resume ioctl failed (%d)\n", errno); - rc = -errno; - goto out_free; - } - -out_free: - free (io); -out_nofree: - close (dmFd); - return rc; -} - -static int AsecDestroyDeviceMapping(struct asec_context *ctx) -{ - struct dm_ioctl *io; - int dmFd; - int rc = 0; - - if ((dmFd = open("/dev/device-mapper", O_RDWR)) < 0) { - LOG_ERROR("Error opening device mapper (%d)\n", errno); - return -errno; - } - - if (!(io = _dm_ioctl_setup(ctx, DM_PERSISTENT_DEV_FLAG))) { - LOG_ERROR("Unable to setup ioctl (out of memory)\n"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(dmFd, DM_DEV_REMOVE, io)) < 0) { - LOG_ERROR("device-mapper remove ioctl failed (%d)\n", errno); - rc = -errno; - goto out_free; - } - -out_free: - free (io); -out_nofree: - close (dmFd); - return rc; -} - -static int AsecMountCache(struct asec_context *ctx) -{ - int flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_NOATIME | MS_NODIRATIME; - char devname[255]; - - if (access(ctx->dstPath, R_OK)) { - LOG_ERROR("Destination mount point '%s' unavailable (%d)\n", ctx->dstPath, errno); - return -errno; - } - - sprintf(devname, "/dev/block/dm-%d", ctx->dm_num); - - if (mount(devname, ctx->dstPath, "ext3", flags, NULL)) { - LOG_ERROR("ASEC mount failed (%d)\n", errno); - return -errno; - } - - return 0; -} - -static int AsecUnmountCache(struct asec_context *ctx) -{ - if (umount(ctx->dstPath)) { - if (errno == EBUSY) { - LOG_ASEC("ASEC volume '%s' still busy\n", ctx->name); - } else { - LOG_ERROR("ASEC umount failed (%d)\n", errno); - } - return -errno; - } - LOG_ASEC("ASEC volume '%s' unmounted\n", ctx->name); - return 0; -} - -static int FindNextAvailableLoop() -{ - int i; - - for (i = 0; i < MAX_LOOP; i++) { - struct loop_info info; - char devname[255]; - int fd; - - sprintf(devname, "/dev/block/loop%d", i); - - if ((fd = open(devname, O_RDONLY)) < 0) { - LOG_ERROR("Unable to open %s (%d)\n", devname, errno); - return -errno; - } - - if (ioctl(fd, LOOP_GET_STATUS, &info) < 0) { - close(fd); - - if (errno == ENXIO) - return i; - - LOG_ERROR("Unable to get loop status for %s (%d)\n", devname, errno); - return -errno; - } - close(fd); - } - return -ENXIO; -} - -static int AsecCreateLoop(struct asec_context *ctx) -{ - char devname[255]; - int device_fd; - int rc = 0; - - ctx->lo_num = FindNextAvailableLoop(); - if (ctx->lo_num < 0) { - LOG_ERROR("No loop devices available\n"); - return -ENXIO; - } - - sprintf(devname, "/dev/block/loop%d", ctx->lo_num); - device_fd = open(devname, O_RDWR); - if (device_fd < 0) { - LOG_ERROR("failed to open loop device (%d)\n", errno); - return -errno; - } - - if (ioctl(device_fd, LOOP_SET_FD, ctx->cacheFd) < 0) { - LOG_ERROR("loop_set_fd ioctl failed (%d)\n", errno); - rc = -errno; - } - close(device_fd); - return rc; -} - -static int AsecDestroyLoop(struct asec_context *ctx) -{ - char devname[255]; - int device_fd; - int rc = 0; - - sprintf(devname, "/dev/block/loop%d", ctx->lo_num); - device_fd = open(devname, O_RDONLY); - if (device_fd < 0) { - LOG_ERROR("Failed to open loop (%d)\n", errno); - return -errno; - } - - if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) { - LOG_ERROR("Failed to destroy loop (%d)\n", errno); - rc = -errno; - } - - close(device_fd); - return rc; -} - -int AsecStart(void *Handle) -{ - struct asec_context *ctx = (struct asec_context *) Handle; - char value[PROPERTY_VALUE_MAX]; - int rc = 0; - - if (!ctx) - return -EINVAL; - - if (ctx->started) - return -EBUSY; - - LOG_ASEC("AsecStart(%s):\n", ctx->name); - - NotifyAsecState(ASEC_BUSY, ctx->dstPath); - - if ((rc = AsecLoadModules()) < 0) { - LOG_ERROR("AsecStart: Failed to load kernel modules\n"); -#ifdef MODULE_FAILURE_IS_FATAL - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; -#endif - } - - if ((rc = AsecLoadGenerateKey(ctx))) { - LOG_ERROR("AsecStart: Failed to load / generate key\n"); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; - } - - if ((rc = AsecOpenCreateCache(ctx)) < 0) { - LOG_ERROR("AsecStart: Failed to open / create cache\n"); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; - } - - if ((rc = AsecCreateLoop(ctx)) < 0) { - LOG_ERROR("AsecStart: Failed to create loop\n"); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - goto fail_closecache; - } - - if ((rc = AsecCreateDeviceMapping(ctx)) < 0) { - LOG_ERROR("AsecStart: Failed to create devmapping (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - goto fail_destroyloop; - } - - if (ctx->needs_format) { - if ((rc = AsecFormatFilesystem(ctx))) { - LOG_ERROR("AsecStart: Failed to format cache (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - goto fail_destroydm; - } - ctx->needs_format = 0; - } else { - if ((rc = AsecCheckFilesystem(ctx))) { - LOG_ERROR("AsecStart: Failed to check filesystem (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - goto fail_destroydm; - } - } - - if ((rc = AsecMountCache(ctx)) < 0) { - LOG_ERROR("AsecStart: Failed to mount cache (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - goto fail_destroydm; - } - - NotifyAsecState(ASEC_AVAILABLE, ctx->dstPath); - ctx->started = true; - - return rc; - - fail_destroydm: - AsecDestroyDeviceMapping(ctx); - fail_destroyloop: - AsecDestroyLoop(ctx); - fail_closecache: - AsecCloseCache(ctx); - return rc; -} - -int AsecStop(void *Handle) -{ - struct asec_context *ctx = (struct asec_context *) Handle; - int rc = 0; - - if (!ctx->started) - return -EINVAL; - - LOG_ASEC("AsecStop(%s):\n", ctx->name); - - NotifyAsecState(ASEC_BUSY, ctx->dstPath); - - if ((rc = AsecUnmountCache(ctx)) < 0) { - LOG_ERROR("AsecStop: Failed to unmount cache (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; - } - - if ((rc = AsecDestroyDeviceMapping(ctx)) < 0) { - LOG_ERROR("AsecStop: Failed to destroy devmapping (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; - } - - if ((rc = AsecDestroyLoop(ctx)) < 0) { - LOG_ERROR("AsecStop: Failed to destroy loop device (%d)\n", rc); - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; - } - - AsecCloseCache(ctx); - - if ((rc = AsecUnloadModules()) < 0) { - if (rc == -EAGAIN) { - LOG_ASEC("AsecStop: Kernel modules still in use\n"); - } else { - LOG_ERROR("AsecStop: Failed to unload kernel modules (%d)\n", rc); -#ifdef MODULE_FAILURE_IS_FATAL - NotifyAsecState(ASEC_FAILED_INTERR, ctx->dstPath); - return rc; -#endif - } - } - - ctx->started = false; - NotifyAsecState(ASEC_DISABLED, ctx->dstPath); - return rc; -} diff --git a/mountd/ASEC.h b/mountd/ASEC.h deleted file mode 100644 index c87b288777aa9cbcdcca30ab601ae19070c10a4a..0000000000000000000000000000000000000000 --- a/mountd/ASEC.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _ASEC_H -#define _ASEC_H - -#define ASEC_STORES_MAX 4 -#define MAX_LOOP 8 - -typedef enum AsecState { - // Feature disabled - ASEC_DISABLED, - - // Feature enabled and operational - ASEC_AVAILABLE, - - // Busy - ASEC_BUSY, - - // Internal Error - ASEC_FAILED_INTERR, - - // No media available - ASEC_FAILED_NOMEDIA, - - // Media is corrupt - ASEC_FAILED_BADMEDIA, - - // Key mismatch - ASEC_FAILED_BADKEY, -} AsecState; - -/* - * ASEC commands - */ -#define ASEC_CMD_SEND_STATUS "asec_send_status" -#define ASEC_CMD_ENABLE "asec_enable" -#define ASEC_CMD_DISABLE "asec_disable" - -/* - * ASEC events - */ - -// These events correspond to the states in the AsecState enum. -// A path to the ASEC mount point follows the colon -#define ASEC_EVENT_DISABLED "asec_disabled:" -#define ASEC_EVENT_AVAILABLE "asec_available:" -#define ASEC_EVENT_BUSY "asec_busy:" -#define ASEC_EVENT_FAILED_INTERR "asec_failed_interror:" -#define ASEC_EVENT_FAILED_NOMEDIA "asec_failed_nomedia" -#define ASEC_EVENT_FAILED_BADMEDIA "asec_failed_badmedia:" -#define ASEC_EVENT_FAILED_BADKEY "asec_failed_badkey:" - -/* - * System Properties - */ - -#define ASEC_ENABLED "asec.enabled" - -#define ASEC_STATUS "ro.asec.status" -#define ASEC_STATUS_DISABLED "disabled" -#define ASEC_STATUS_AVAILABLE "available" -#define ASEC_STATUS_BUSY "busy" -#define ASEC_STATUS_FAILED_INTERR "internal_error" -#define ASEC_STATUS_FAILED_NOMEDIA "no_media" -#define ASEC_STATUS_FAILED_BADMEDIA "bad_media" -#define ASEC_STATUS_FAILED_BADKEY "bad_key" - -#endif diff --git a/mountd/Android.mk b/mountd/Android.mk deleted file mode 100644 index 16532fa04321f3a172bff33c171b7f2dbb1eabc4..0000000000000000000000000000000000000000 --- a/mountd/Android.mk +++ /dev/null @@ -1,22 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - AutoMount.c \ - ProcessKiller.c \ - Server.c \ - mountd.c \ - ASEC.c \ - logwrapper.c - -LOCAL_MODULE:= mountd - -LOCAL_C_INCLUDES := $(KERNEL_HEADERS) - -LOCAL_CFLAGS := -DCREATE_MOUNT_POINTS=0 - -LOCAL_SHARED_LIBRARIES := libcutils - -# disabled - we are using vold now instead -# include $(BUILD_EXECUTABLE) diff --git a/mountd/AutoMount.c b/mountd/AutoMount.c deleted file mode 100644 index 12ad572e9222eb315326eac6448e4df391b838fb..0000000000000000000000000000000000000000 --- a/mountd/AutoMount.c +++ /dev/null @@ -1,1062 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** mountd automount support -*/ - -#include "mountd.h" - -#include <pthread.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <fcntl.h> -#include <ctype.h> -#include <pwd.h> -#include <stdlib.h> -#include <poll.h> - -#include <sys/mount.h> -#include <sys/stat.h> -#include <linux/loop.h> -#include <sys/inotify.h> -#include <sys/socket.h> -#include <sys/un.h> -#include <linux/netlink.h> - -#define DEVPATH "/dev/block/" -#define DEVPATHLENGTH 11 // strlen(DEVPATH) - -// FIXME - only one loop mount is supported at a time -#define LOOP_DEVICE "/dev/block/loop0" - -// timeout value for poll() when retries are pending -#define POLL_TIMEOUT 1000 - -#define MAX_MOUNT_RETRIES 3 -#define MAX_UNMOUNT_RETRIES 5 - -typedef enum { - // device is unmounted - kUnmounted, - - // attempting to mount device - kMounting, - - // device is unmounted - kMounted, - - // attempting to unmount device - // so the media can be removed - kUnmountingForEject, - - // attempting to mount device - // so it can be shared via USB mass storage - kUnmountingForUms, -} MountState; - -typedef struct MountPoint { - // block device to mount - const char* device; - - // mount point for device - const char* mountPoint; - - // path to the UMS driver file for specifying the block device path - const char* driverStorePath; - - // true if device can be shared via - // USB mass storage - boolean enableUms; - - // Array of ASEC handles - void *asecHandles[ASEC_STORES_MAX]; - - // true if the device is being shared via USB mass storage - boolean umsActive; - - // current state of the mount point - MountState state; - - // number of mount or unmount retries so far, - // when attempting to mount or unmount the device - int retryCount; - - // next in sMountPointList linked list - struct MountPoint* next; -} MountPoint; - -// list of our mount points (does not change after initialization) -static MountPoint* sMountPointList = NULL; -boolean gMassStorageEnabled = false; -boolean gMassStorageConnected = false; - -static pthread_t sAutoMountThread = 0; -static pid_t gExcludedPids[2] = {-1, -1}; - -static const char FSCK_MSDOS_PATH[] = "/system/bin/dosfsck"; - -// number of mount points that have timeouts pending -static int sRetriesPending = 0; - -// for synchronization between sAutoMountThread and the server thread -static pthread_mutex_t sMutex = PTHREAD_MUTEX_INITIALIZER; - -// requests the USB mass_storage driver to begin or end sharing a block device -// via USB mass storage. -static void SetBackingStore(MountPoint* mp, boolean enable) -{ - int fd; - - if (!mp->driverStorePath) { - LOG_ERROR("no driver_store_path specified in config file for %s", mp->device); - return; - } - - LOG_MOUNT("SetBackingStore enable: %s\n", (enable ? "true" : "false")); - fd = open(mp->driverStorePath, O_WRONLY); - if (fd < 0) - { - LOG_ERROR("could not open driver_store_path %s\n", mp->driverStorePath); - } - else - { - if (enable) - { - write(fd, mp->device, strlen(mp->device)); - mp->umsActive = true; - } - else - { - char ch = 0; - write(fd, &ch, 1); - mp->umsActive = false; - } - close(fd); - } -} - -static boolean ReadMassStorageState() -{ - FILE* file = fopen("/sys/class/switch/usb_mass_storage/state", "r"); - if (file) - { - char buffer[20]; - fgets(buffer, sizeof(buffer), file); - fclose(file); - return (strncmp(buffer, "online", strlen("online")) == 0); - } - else - { - LOG_ERROR("could not read initial mass storage state\n"); - return false; - } -} - -static boolean IsLoopMounted(const char* path) -{ - FILE* f; - int count; - char device[256]; - char mount_path[256]; - char rest[256]; - int result = 0; - int path_length = strlen(path); - - f = fopen("/proc/mounts", "r"); - if (!f) { - LOG_ERROR("could not open /proc/mounts\n"); - return -1; - } - - do { - count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest); - if (count == 3) { - if (strcmp(LOOP_DEVICE, device) == 0 && strcmp(path, mount_path) == 0) - { - result = 1; - break; - } - } - } while (count == 3); - - fclose(f); - LOG_MOUNT("IsLoopMounted: %s returning %d\n", path, result); - return result; -} - -static int CheckFilesystem(const char *device) -{ - char cmdline[255]; - int rc; - - // XXX: SAN: Check for FAT signature - - int result = access(FSCK_MSDOS_PATH, X_OK); - if (result != 0) { - LOG_MOUNT("CheckFilesystem(%s): %s not found (skipping checks)\n", FSCK_MSDOS_PATH, device); - return 0; - } - - char *args[7]; - args[0] = FSCK_MSDOS_PATH; - args[1] = "-v"; - args[2] = "-V"; - args[3] = "-w"; - args[4] = "-p"; - args[5] = device; - args[6] = NULL; - - LOG_MOUNT("Checking filesystem on %s\n", device); - rc = logwrap(6, args); - - // XXX: We need to be able to distinguish between a FS with an error - // and a block device which does not have a FAT fs at all on it - if (rc == 0) { - LOG_MOUNT("Filesystem check completed OK\n"); - return 0; - } else if (rc == 1) { - LOG_MOUNT("Filesystem check failed (general failure)\n"); - return -EINVAL; - } else if (rc == 2) { - LOG_MOUNT("Filesystem check failed (invalid usage)\n"); - return -EIO; - } else { - LOG_MOUNT("Filesystem check failed (unknown exit code %d)\n", rc); - return -EIO; - } -} - -static int DoMountDevice(const char* device, const char* mountPoint) -{ - LOG_MOUNT("Attempting mount of %s on %s\n", device, mountPoint); - -#if CREATE_MOUNT_POINTS - // make sure mount point exists - mkdir(mountPoint, 0000); -#endif - - int flags = 0; - - if (device && strncmp(device, "/dev/", 5)) - { - // mount with the loop driver if device does not start with "/dev/" - int file_fd, device_fd; - - // FIXME - only one loop mount supported at a time - file_fd = open(device, O_RDWR); - if (file_fd < -1) { - LOG_ERROR("open backing file %s failed\n", device); - return 1; - } - device_fd = open(LOOP_DEVICE, O_RDWR); - if (device_fd < -1) { - LOG_ERROR("open %s failed", LOOP_DEVICE); - close(file_fd); - return 1; - } - if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) - { - LOG_ERROR("ioctl LOOP_SET_FD failed\n"); - close(file_fd); - close(device_fd); - return 1; - } - - close(file_fd); - close(device_fd); - device = "/dev/block/loop0"; - } - - int result = access(device, R_OK); - if (result) { - LOG_ERROR("Unable to access '%s' (%d)\n", device, errno); - return -errno; - } - -#if 0 - if ((result = CheckFilesystem(device))) { - LOG_ERROR("Not mounting filesystem due to check failure (%d)\n", result); - // XXX: Notify framework - need a new SDCARD state for the following: - // - SD cards which are not present - // - SD cards with no partition table - // - SD cards with no filesystem - // - SD cards with bad filesystem - return result; - } -#endif - - // Extra safety measures: - flags |= MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC; - // Also, set fmask = 711 so that files cannot be marked executable, - // and cannot by opened by uid 1000 (system). Similar, dmask = 700 - // so that directories cannot be accessed by uid 1000. - result = mount(device, mountPoint, "vfat", flags, - "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); - if (result && errno == EROFS) { - LOG_ERROR("mount failed EROFS, try again read-only\n"); - flags |= MS_RDONLY; - result = mount(device, mountPoint, "vfat", flags, - "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); - } - - if (result == 0) { - LOG_MOUNT("Partition %s mounted on %s\n", device, mountPoint); - NotifyMediaState(mountPoint, MEDIA_MOUNTED, (flags & MS_RDONLY) != 0); - - MountPoint* mp = sMountPointList; - while (mp) { - if (!strcmp(mountPoint, mp->mountPoint)) { - int i; - - for (i = 0; i < ASEC_STORES_MAX; i++) { - if (mp->asecHandles[i] != NULL) { - int a_result; - if ((a_result = AsecStart(mp->asecHandles[i])) < 0) { - LOG_ERROR("ASEC start failure (%d)\n", a_result); - } - } - } - break; - } - mp = mp -> next; - } - } else if (errno == EBUSY) { - LOG_MOUNT("Mount failed (already mounted)\n"); - result = 0; - } else { -#if CREATE_MOUNT_POINTS - rmdir(mountPoint); -#endif - LOG_MOUNT("Unable to mount %s on %s\n", device, mountPoint); - } - - return result; -} - -static int DoUnmountDevice(MountPoint *mp) -{ - boolean loop = IsLoopMounted(mp->mountPoint); - int i; - - for (i = 0; i < ASEC_STORES_MAX; i++) { - if (mp->asecHandles[i] && AsecIsStarted(mp->asecHandles[i])) - AsecStop(mp->asecHandles[i]); - } - - int result = umount(mp->mountPoint); - LOG_MOUNT("umount returned %d errno: %d\n", result, errno); - - if (result == 0) - { -#if CREATE_MOUNT_POINTS - rmdir(mountPoint); -#endif - NotifyMediaState(mp->mountPoint, MEDIA_UNMOUNTED, false); - } - - if (loop) - { - // free the loop device - int loop_fd = open(LOOP_DEVICE, O_RDONLY); - if (loop_fd < -1) { - LOG_ERROR("open loop device failed\n"); - } - if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) { - LOG_ERROR("ioctl LOOP_CLR_FD failed\n"); - } - - close(loop_fd); - } - - // ignore EINVAL and ENOENT, since it usually means the device is already unmounted - if (result && (errno == EINVAL || errno == ENOENT)) - result = 0; - - return result; -} - -static int MountPartition(const char* device, const char* mountPoint) -{ - char buf[100]; - int i; - - // attempt to mount subpartitions of the device - for (i = 1; i < 10; i++) - { - int rc; - snprintf(buf, sizeof(buf), "%sp%d", device, i); - rc = DoMountDevice(buf, mountPoint); - LOG_MOUNT("DoMountDevice(%s, %s) = %d\n", buf, mountPoint, rc); - if (rc == 0) - return 0; - } - - return -1; -} - -/***************************************************** - * - * AUTO-MOUNTER STATE ENGINE IMPLEMENTATION - * - *****************************************************/ - -static void SetState(MountPoint* mp, MountState state) -{ - mp->state = state; -} - -// Enter a state that requires retries and timeouts. -static void SetRetries(MountPoint* mp, MountState state) -{ - SetState(mp, state); - mp->retryCount = 0; - - sRetriesPending++; - // wake up the automounter thread if we are being called - // from somewhere else with no retries pending - if (sRetriesPending == 1 && sAutoMountThread != 0 && - pthread_self() != sAutoMountThread) - pthread_kill(sAutoMountThread, SIGUSR1); -} - -// Exit a state that requires retries and timeouts. -static void ClearRetries(MountPoint* mp, MountState state) -{ - SetState(mp, state); - sRetriesPending--; -} - -// attempt to mount the specified mount point. -// set up retry/timeout if it does not succeed at first. -static void RequestMount(MountPoint* mp) -{ - LOG_MOUNT("RequestMount %s\n", mp->mountPoint); - - if (mp->state != kMounted && mp->state != kMounting && - access(mp->device, R_OK) == 0) { - // try raw device first - if (DoMountDevice(mp->device, mp->mountPoint) == 0 || - MountPartition(mp->device, mp->mountPoint) == 0) - { - SetState(mp, kMounted); - } - else - { - SetState(mp, kMounting); - mp->retryCount = 0; - SetRetries(mp, kMounting); - } - } -} - -// Force the kernel to drop all caches. -static void DropSystemCaches(void) -{ - int fd; - - LOG_MOUNT("Dropping system caches\n"); - fd = open("/proc/sys/vm/drop_caches", O_WRONLY); - - if (fd > 0) { - char ch = 3; - int rc; - - rc = write(fd, &ch, 1); - if (rc <= 0) - LOG_MOUNT("Error dropping caches (%d)\n", rc); - close(fd); - } -} - -// attempt to unmount the specified mount point. -// set up retry/timeout if it does not succeed at first. -static void RequestUnmount(MountPoint* mp, MountState retryState) -{ - int result; - - LOG_MOUNT("RequestUnmount %s retryState: %d\n", mp->mountPoint, retryState); - - if (mp->state == kMounted) - { - SendUnmountRequest(mp->mountPoint); - - // do this in case the user pulls the SD card before we can successfully unmount - sync(); - DropSystemCaches(); - - if (DoUnmountDevice(mp) == 0) - { - SetState(mp, kUnmounted); - if (retryState == kUnmountingForUms) - { - SetBackingStore(mp, true); - NotifyMediaState(mp->mountPoint, MEDIA_SHARED, false); - } - } - else - { - LOG_MOUNT("unmount failed, set retry\n"); - SetRetries(mp, retryState); - } - } - else if (mp->state == kMounting) - { - SetState(mp, kUnmounted); - } -} - -// returns true if the mount point should be shared via USB mass storage -static boolean MassStorageEnabledForMountPoint(const MountPoint* mp) -{ - return (gMassStorageEnabled && gMassStorageConnected && mp->enableUms); -} - -// handles changes in gMassStorageEnabled and gMassStorageConnected -static void MassStorageStateChanged() -{ - MountPoint* mp = sMountPointList; - - boolean enable = (gMassStorageEnabled && gMassStorageConnected); - LOG_MOUNT("MassStorageStateChanged enable: %s\n", (enable ? "true" : "false")); - - while (mp) - { - if (mp->enableUms) - { - if (enable) - { - if (mp->state == kMounting) - SetState(mp, kUnmounted); - if (mp->state == kUnmounted) - { - SetBackingStore(mp, true); - NotifyMediaState(mp->mountPoint, MEDIA_SHARED, false); - } - else - { - LOG_MOUNT("MassStorageStateChanged requesting unmount\n"); - // need to successfully unmount first - RequestUnmount(mp, kUnmountingForUms); - } - } else if (mp->umsActive) { - SetBackingStore(mp, false); - if (mp->state == kUnmountingForUms) - { - ClearRetries(mp, kMounted); - NotifyMediaState(mp->mountPoint, MEDIA_MOUNTED, false); - } - else if (mp->state == kUnmounted) - { - NotifyMediaState(mp->mountPoint, MEDIA_UNMOUNTED, false); - RequestMount(mp); - } - } - } - - mp = mp->next; - } -} - -// called when USB mass storage connected state changes -static void HandleMassStorageOnline(boolean connected) -{ - if (connected != gMassStorageConnected) - { - gMassStorageConnected = connected; - SendMassStorageConnected(connected); - - // we automatically reset to mass storage off after USB is connected - if (!connected) - gMassStorageEnabled = false; - - MassStorageStateChanged(); - } -} - -// called when a new block device has been created -static void HandleMediaInserted(const char* device) -{ - MountPoint* mp = sMountPointList; - - LOG_MOUNT("HandleMediaInserted(%s):\n", device); - - while (mp) - { - // see if the device matches mount point's block device - if (mp->state == kUnmounted && - strncmp(device, mp->device + DEVPATHLENGTH, strlen(mp->device) - DEVPATHLENGTH) == 0) - { - if (MassStorageEnabledForMountPoint(mp)) - { - SetBackingStore(mp, true); - NotifyMediaState(mp->mountPoint, MEDIA_SHARED, false); - } - else - RequestMount(mp); - } - mp = mp->next; - } -} - -// called when a new block device has been deleted -static void HandleMediaRemoved(const char* device) -{ - MountPoint* mp = sMountPointList; - while (mp) - { - if (strncmp(device, mp->device + DEVPATHLENGTH, strlen(mp->device) - DEVPATHLENGTH) == 0) - { - if (mp->enableUms) - SetBackingStore(mp, false); - - if (mp->state == kMounted) - { - RequestUnmount(mp, kUnmountingForEject); - NotifyMediaState(mp->mountPoint, MEDIA_BAD_REMOVAL, false); - } - - NotifyMediaState(mp->mountPoint, MEDIA_REMOVED, false); - break; - } - mp = mp->next; - } -} - -// Handle retrying to mount or unmount devices, -// and handle timeout condition if we have tried too many times -static void HandleRetries() -{ - MountPoint* mp = sMountPointList; - - while (mp) - { - if (mp->state == kMounting) - { - if (MountPartition(mp->device, mp->mountPoint) == 0) - { - // mount succeeded - clear the retry for this mount point - ClearRetries(mp, kMounted); - } - else - { - mp->retryCount++; - if (mp->retryCount == MAX_MOUNT_RETRIES) - { - // we failed to mount the device too many times - ClearRetries(mp, kUnmounted); - // notify that we failed to mount - NotifyMediaState(mp->mountPoint, MEDIA_UNMOUNTABLE, false); - } - } - } - else if (mp->state == kUnmountingForEject || mp->state == kUnmountingForUms) - { - if (DoUnmountDevice(mp) == 0) - { - // unmounting succeeded - // start mass storage, if state is kUnmountingForUms - if (mp->state == kUnmountingForUms) - { - SetBackingStore(mp, true); - NotifyMediaState(mp->mountPoint, MEDIA_SHARED, false); - } - // clear the retry for this mount point - ClearRetries(mp, kUnmounted); - } - else - { - mp->retryCount++; - if (mp->retryCount >= MAX_UNMOUNT_RETRIES) - { - // kill any processes that are preventing the device from unmounting - // send SIGKILL instead of SIGTERM if the first attempt did not succeed - boolean sigkill = (mp->retryCount > MAX_UNMOUNT_RETRIES); - - int i; - - for (i = 0; i < ASEC_STORES_MAX; i++) { - if (mp->asecHandles[i] && AsecIsStarted(mp->asecHandles[i])) { - LOG_MOUNT("Killing processes for ASEC path '%s'\n", - AsecMountPoint(mp->asecHandles[i])); - KillProcessesWithOpenFiles(AsecMountPoint(mp->asecHandles[i]), - sigkill, - gExcludedPids, sizeof(gExcludedPids) / sizeof(pid_t)); - - // Now that we've killed the processes, try to stop the volume again - AsecStop(mp->asecHandles[i]); - } - } - - // unmounting the device is failing, so start killing processes - KillProcessesWithOpenFiles(mp->mountPoint, sigkill, gExcludedPids, - sizeof(gExcludedPids) / sizeof(pid_t)); - - } - } - } - - mp = mp->next; - } -} - -/***************************************************** - * - * AUTO-MOUNTER THREAD - * - *****************************************************/ - -static void sigusr1_handler(int signo) -{ - // don't need to do anything here -} - -// create a socket for listening to inotify events -int CreateINotifySocket() -{ - // initialize inotify - int fd = inotify_init(); - - if (fd < 0) { - LOG_ERROR("inotify_init failed, %s\n", strerror(errno)); - return -1; - } - - fcntl(fd, F_SETFL, O_NONBLOCK | fcntl(fd, F_GETFL)); - - return fd; -} - - -// create a socket for listening to uevents -int CreateUEventSocket() -{ - struct sockaddr_nl addr; - int sz = 64*1024; - int fd; - - memset(&addr, 0, sizeof(addr)); - addr.nl_family = AF_NETLINK; - addr.nl_pid = getpid(); - addr.nl_groups = 0xffffffff; - - fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT); - if(fd < 0) - { - LOG_ERROR("could not create NETLINK_KOBJECT_UEVENT socket\n"); - return -1; - } - - setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)); - - if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) { - LOG_ERROR("could not bind NETLINK_KOBJECT_UEVENT socket\n"); - close(fd); - return -1; - } - - return fd; -} - -/* - * Automounter main event thread. - * This thread listens for block devices being created and deleted via inotify, - * and listens for changes in the USB mass storage connected/disconnected via uevents from the - * power supply driver. - * This thread also handles retries and timeouts for requests to mount or unmount a device. - */ -static void* AutoMountThread(void* arg) -{ - int inotify_fd; - int uevent_fd; - int id; - struct sigaction actions; - - gExcludedPids[1] = getpid(); - - memset(&actions, 0, sizeof(actions)); - sigemptyset(&actions.sa_mask); - actions.sa_flags = 0; - actions.sa_handler = sigusr1_handler; - sigaction(SIGUSR1, &actions, NULL); - - // initialize inotify - inotify_fd = CreateINotifySocket(); - // watch for files created and deleted in "/dev" - inotify_add_watch(inotify_fd, DEVPATH, IN_CREATE|IN_DELETE); - - // initialize uevent watcher - uevent_fd = CreateUEventSocket(); - if (uevent_fd < 0) - { - LOG_ERROR("CreateUEventSocket failed, %s\n", strerror(errno)); - return NULL; - } - - while (1) - { - struct pollfd fds[2]; - int timeout, result; - -#define INOTIFY_IDX 0 -#define UEVENT_IDX 1 - - fds[INOTIFY_IDX].fd = inotify_fd; - fds[INOTIFY_IDX].events = POLLIN; - fds[INOTIFY_IDX].revents = 0; - fds[UEVENT_IDX].fd = uevent_fd; - fds[UEVENT_IDX].events = POLLIN; - fds[UEVENT_IDX].revents = 0; - - // wait for an event or a timeout to occur. - // poll() can also return in response to a SIGUSR1 signal - timeout = (sRetriesPending ? POLL_TIMEOUT : -1); - result = poll(fds, 2, timeout); - - // lock the mutex while we are handling events - pthread_mutex_lock(&sMutex); - - // handle inotify notifications for block device creation and deletion - if (fds[INOTIFY_IDX].revents == POLLIN) - { - struct inotify_event event; - char buffer[512]; - int length = read(inotify_fd, buffer, sizeof(buffer)); - int offset = 0; - - while (length >= (int)sizeof(struct inotify_event)) - { - struct inotify_event* event = (struct inotify_event *)&buffer[offset]; - - if (event->mask == IN_CREATE) - { - LOG_MOUNT("/dev/block/%s created\n", event->name); - HandleMediaInserted(event->name); - } - else if (event->mask == IN_DELETE) - { - LOG_MOUNT("/dev/block/%s deleted\n", event->name); - HandleMediaRemoved(event->name); - } - - int size = sizeof(struct inotify_event) + event->len; - length -= size; - offset += size; - } - } - - // handle uevent notifications for USB state changes - if (fds[UEVENT_IDX].revents == POLLIN) - { - char buffer[64*1024]; - int count; - - count = recv(uevent_fd, buffer, sizeof(buffer), 0); - if (count > 0) { - char* s = buffer; - char* end = s + count; - char* type = NULL; - char* online = NULL; - char* switchName = NULL; - char* switchState = NULL; - - while (s < end) { - if (!strncmp("POWER_SUPPLY_TYPE=", s, strlen("POWER_SUPPLY_TYPE="))) - type = s + strlen("POWER_SUPPLY_TYPE="); - else if (!strncmp("POWER_SUPPLY_ONLINE=", s, strlen("POWER_SUPPLY_ONLINE="))) - online = s + strlen("POWER_SUPPLY_ONLINE="); - else if (!strncmp("SWITCH_NAME=", s, strlen("SWITCH_NAME="))) - switchName = s + strlen("SWITCH_NAME="); - else if (!strncmp("SWITCH_STATE=", s, strlen("SWITCH_STATE="))) - switchState = s + strlen("SWITCH_STATE="); - s += (strlen(s) + 1); - } - - // we use the usb_mass_storage switch state to tell us when USB is online - if (switchName && switchState && - !strcmp(switchName, "usb_mass_storage") && !strcmp(switchState, "online")) - { - LOG_MOUNT("USB online\n"); - HandleMassStorageOnline(true); - } - - // and we use the power supply state to tell us when USB is offline - // we can't rely on the switch for offline detection because we get false positives - // when USB is reenumerated by the host. - if (type && online && !strcmp(type, "USB") && !strcmp(online, "0")) - { - LOG_MOUNT("USB offline\n"); - HandleMassStorageOnline(false); - } - } - } - - // handle retries - if (sRetriesPending) - HandleRetries(); - - // done handling events, so unlock the mutex - pthread_mutex_unlock(&sMutex); - } - - inotify_rm_watch(inotify_fd, id); - close(inotify_fd); - close(uevent_fd); - - return NULL; -} - -/***************************************************** - * - * THESE FUNCTIONS ARE CALLED FROM THE SERVER THREAD - * - *****************************************************/ - -// Called to enable or disable USB mass storage support -void EnableMassStorage(boolean enable) -{ - pthread_mutex_lock(&sMutex); - - LOG_MOUNT("EnableMassStorage %s\n", (enable ? "true" : "false")); - gMassStorageEnabled = enable; - MassStorageStateChanged(); - pthread_mutex_unlock(&sMutex); - } - -// Called to request that the specified mount point be mounted -void MountMedia(const char* mountPoint) -{ - MountPoint* mp = sMountPointList; - - LOG_MOUNT("MountMedia(%s)\n", mountPoint); - - pthread_mutex_lock(&sMutex); - while (mp) - { - if (strcmp(mp->mountPoint, mountPoint) == 0) - { - if (mp->state == kUnmountingForEject) - { - // handle the case where we try to remount before we actually unmounted - ClearRetries(mp, kMounted); - } - - // don't attempt to mount if mass storage is active - if (!MassStorageEnabledForMountPoint(mp)) - RequestMount(mp); - } - - mp = mp->next; - } - pthread_mutex_unlock(&sMutex); - } - -// Called to request that the specified mount point be unmounted -void UnmountMedia(const char* mountPoint) -{ - MountPoint* mp = sMountPointList; - - pthread_mutex_lock(&sMutex); - while (mp) - { - if (strcmp(mp->mountPoint, mountPoint) == 0) - RequestUnmount(mp, kUnmountingForEject); - - mp = mp->next; - } - pthread_mutex_unlock(&sMutex); -} - -boolean IsMassStorageEnabled() -{ - return gMassStorageEnabled; -} - -boolean IsMassStorageConnected() -{ - return gMassStorageConnected; -} - -/*********************************************** - * - * THESE FUNCTIONS ARE CALLED ONLY AT STARTUP - * - ***********************************************/ - -void *AddMountPoint(const char* device, const char* mountPoint, const char * driverStorePath, boolean enableUms) -{ - MountPoint* newMountPoint; - - LOG_MOUNT("AddMountPoint device: %s, mountPoint: %s driverStorePath: %s\n", device, mountPoint, driverStorePath); - // add a new MountPoint to the head of our linked list - newMountPoint = (MountPoint *)malloc(sizeof(MountPoint)); - newMountPoint->device = device; - newMountPoint->mountPoint = mountPoint; - newMountPoint->driverStorePath = driverStorePath; - newMountPoint->enableUms = enableUms; - newMountPoint->umsActive = false; - newMountPoint->state = kUnmounted; - newMountPoint->retryCount = 0; - - // add to linked list - newMountPoint->next = sMountPointList; - sMountPointList = newMountPoint; - return newMountPoint; -} - -int AddAsecToMountPoint(void *Mp, const char *name, const char *backing_file, const char *size, - const char *mount_point, const char *crypt) -{ - MountPoint *mp = (MountPoint *) Mp; - int i; - - for (i = 0; i < ASEC_STORES_MAX; i++) { - if (!mp->asecHandles[i]) - break; - } - - if (i == ASEC_STORES_MAX) { - LOG_ERROR("Maximum # of ASEC stores exceeded\n"); - return -EINVAL; - } - - if (!(mp->asecHandles[i] = AsecInit(name, mp->mountPoint, backing_file, size, mount_point, crypt))) - return -1; - - return 0; -} -static void MountDevices() -{ - MountPoint* mp = sMountPointList; - while (mp) - { - RequestMount(mp); - mp = mp->next; - } -} - -void StartAutoMounter() -{ - gExcludedPids[0] = getpid(); - - gMassStorageConnected = ReadMassStorageState(); - LOG_MOUNT(gMassStorageConnected ? "USB online\n" : "USB offline\n"); - - MountDevices(); - pthread_create(&sAutoMountThread, NULL, AutoMountThread, NULL); -} diff --git a/mountd/MODULE_LICENSE_APACHE2 b/mountd/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/mountd/NOTICE b/mountd/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/mountd/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/mountd/ProcessKiller.c b/mountd/ProcessKiller.c deleted file mode 100644 index e37777446d54396434d4d96b4379f6ecb1bb4877..0000000000000000000000000000000000000000 --- a/mountd/ProcessKiller.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** mountd process killer -*/ - -#include "mountd.h" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <dirent.h> -#include <ctype.h> -#include <pwd.h> -#include <stdlib.h> -#include <poll.h> -#include <sys/stat.h> - - -static boolean ReadSymLink(const char* path, char* link) -{ - struct stat s; - int length; - - if (lstat(path, &s) < 0) - return false; - if ((s.st_mode & S_IFMT) != S_IFLNK) - return false; - - // we have a symlink - length = readlink(path, link, PATH_MAX - 1); - if (length <= 0) - return false; - link[length] = 0; - return true; -} - -static boolean PathMatchesMountPoint(const char* path, const char* mountPoint) -{ - int length = strlen(mountPoint); - if (length > 1 && strncmp(path, mountPoint, length) == 0) - { - // we need to do extra checking if mountPoint does not end in a '/' - if (mountPoint[length - 1] == '/') - return true; - // if mountPoint does not have a trailing slash, we need to make sure - // there is one in the path to avoid partial matches. - return (path[length] == 0 || path[length] == '/'); - } - - return false; -} - -static void GetProcessName(int pid, char buffer[PATH_MAX]) -{ - int fd; - sprintf(buffer, "/proc/%d/cmdline", pid); - fd = open(buffer, O_RDONLY); - if (fd < 0) { - strcpy(buffer, "???"); - } else { - int length = read(fd, buffer, PATH_MAX - 1); - buffer[length] = 0; - close(fd); - } -} - -static boolean CheckFileDescriptorSymLinks(int pid, const char* mountPoint) -{ - DIR* dir; - struct dirent* de; - boolean fileOpen = false; - char path[PATH_MAX]; - char link[PATH_MAX]; - int parent_length; - - // compute path to process's directory of open files - sprintf(path, "/proc/%d/fd", pid); - dir = opendir(path); - if (!dir) - return false; - - // remember length of the path - parent_length = strlen(path); - // append a trailing '/' - path[parent_length++] = '/'; - - while ((de = readdir(dir)) != 0 && !fileOpen) { - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; - - // append the file name, after truncating to parent directory - path[parent_length] = 0; - strcat(path, de->d_name); - - if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has open file %s\n", name, pid, link); - fileOpen = true; - } - } - - closedir(dir); - return fileOpen; -} - -static boolean CheckFileMaps(int pid, const char* mountPoint) -{ - FILE* file; - char buffer[PATH_MAX + 100]; - boolean mapOpen = false; - - sprintf(buffer, "/proc/%d/maps", pid); - file = fopen(buffer, "r"); - if (!file) - return false; - - while (!mapOpen && fgets(buffer, sizeof(buffer), file)) - { - // skip to the path - const char* path = strchr(buffer, '/'); - if (path && PathMatchesMountPoint(path, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has open file map for %s\n", name, pid, path); - mapOpen = true; - } - } - - fclose(file); - return mapOpen; -} - -static boolean CheckSymLink(int pid, const char* mountPoint, const char* name, const char* message) -{ - char path[PATH_MAX]; - char link[PATH_MAX]; - - sprintf(path, "/proc/%d/%s", pid, name); - if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has %s in %s\n", name, pid, message, mountPoint); - return true; - } - else - return false; -} - -static int get_pid(const char* s) -{ - int result = 0; - while (*s) { - if (!isdigit(*s)) return -1; - result = 10 * result + (*s++ - '0'); - } - return result; -} - -// hunt down and kill processes that have files open on the given mount point -void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *excluded, int num_excluded) -{ - DIR* dir; - struct dirent* de; - - LOG_ERROR("KillProcessesWithOpenFiles %s\n", mountPoint); - dir = opendir("/proc"); - if (!dir) return; - - while ((de = readdir(dir)) != 0) - { - boolean killed = false; - // does the name look like a process ID? - int pid = get_pid(de->d_name); - if (pid == -1) continue; - - if (CheckFileDescriptorSymLinks(pid, mountPoint) // check for open files - || CheckFileMaps(pid, mountPoint) // check for mmap() - || CheckSymLink(pid, mountPoint, "cwd", "working directory") // check working directory - || CheckSymLink(pid, mountPoint, "root", "chroot") // check for chroot() - || CheckSymLink(pid, mountPoint, "exe", "executable path") // check executable path - ) - { - int i; - boolean hit = false; - - for (i = 0; i < num_excluded; i++) { - if (pid == excluded[i]) { - LOG_ERROR("I just need a little more TIME captain!\n"); - hit = true; - break; - } - } - - if (!hit) { - LOG_ERROR("Killing process %d\n", pid); - kill(pid, (sigkill ? SIGKILL : SIGTERM)); - } - } - } - - closedir(dir); -} diff --git a/mountd/Server.c b/mountd/Server.c deleted file mode 100644 index 64459bd88360641304027517bf64d42e5e6df252..0000000000000000000000000000000000000000 --- a/mountd/Server.c +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** mountd server support -*/ - -#include "mountd.h" -#include "ASEC.h" - -#include <cutils/properties.h> -#include <cutils/sockets.h> - -#include <pthread.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <sys/socket.h> - -#include <private/android_filesystem_config.h> - - -// current client file descriptor -static int sFD = -1; - -// to synchronize writing to client -static pthread_mutex_t sWriteMutex = PTHREAD_MUTEX_INITIALIZER; - -// path for media that failed to mount before the runtime is connected -static char* sDeferredUnmountableMediaPath = NULL; - -// last asec msg before the runtime was connected -static char* sAsecDeferredMessage = NULL; -static char* sAsecDeferredArgument = NULL; - -static int Write(const char* message) -{ - int result = -1; - - pthread_mutex_lock(&sWriteMutex); - - LOG_SERVER("Write: %s\n", message); - if (sFD >= 0) - result = write(sFD, message, strlen(message) + 1); - - pthread_mutex_unlock(&sWriteMutex); - - return result; -} - -static int Write2(const char* message, const char* data) -{ - int result = -1; - - char* buffer = (char *)alloca(strlen(message) + strlen(data) + 1); - if (!buffer) - { - LOG_ERROR("alloca failed in Write2\n"); - return -1; - } - - strcpy(buffer, message); - strcat(buffer, data); - return Write(buffer); -} - -static void SendStatus() -{ - Write(IsMassStorageConnected() ? MOUNTD_UMS_CONNECTED : MOUNTD_UMS_DISCONNECTED); - Write(IsMassStorageEnabled() ? MOUNTD_UMS_ENABLED : MOUNTD_UMS_DISABLED); -} - -static void DoCommand(const char* command) -{ - LOG_SERVER("DoCommand %s\n", command); - - if (strcmp(command, MOUNTD_ENABLE_UMS) == 0) - { - EnableMassStorage(true); - Write(MOUNTD_UMS_ENABLED); - } - else if (strcmp(command, MOUNTD_DISABLE_UMS) == 0) - { - EnableMassStorage(false); - Write(MOUNTD_UMS_DISABLED); - } - else if (strcmp(command, MOUNTD_SEND_STATUS) == 0) - { - SendStatus(); - } - else if (strncmp(command, MOUNTD_MOUNT_MEDIA, strlen(MOUNTD_MOUNT_MEDIA)) == 0) - { - const char* path = command + strlen(MOUNTD_MOUNT_MEDIA); - MountMedia(path); - } - else if (strncmp(command, MOUNTD_EJECT_MEDIA, strlen(MOUNTD_EJECT_MEDIA)) == 0) - { - const char* path = command + strlen(MOUNTD_EJECT_MEDIA); - UnmountMedia(path); - } - else if (strncmp(command, ASEC_CMD_ENABLE, strlen(ASEC_CMD_ENABLE)) == 0) { - LOG_ASEC("Got ASEC_CMD_ENABLE\n"); - // XXX: SAN: Impliment - } - else if (strncmp(command, ASEC_CMD_DISABLE, strlen(ASEC_CMD_DISABLE)) == 0) { - LOG_ASEC("Got ASEC_CMD_DISABLE\n"); - // XXX: SAN: Impliment - } - else if (strncmp(command, ASEC_CMD_SEND_STATUS, strlen(ASEC_CMD_SEND_STATUS)) == 0) { - LOG_ASEC("Got ASEC_CMD_SEND_STATUS\n"); - // XXX: SAN: Impliment - } - else - LOGE("unknown command %s\n", command); -} - -int RunServer() -{ - int socket = android_get_control_socket(MOUNTD_SOCKET); - if (socket < 0) { - LOGE("Obtaining file descriptor for socket '%s' failed: %s", - MOUNTD_SOCKET, strerror(errno)); - return -1; - } - - if (listen(socket, 4) < 0) { - LOGE("Unable to listen on file descriptor '%d' for socket '%s': %s", - socket, MOUNTD_SOCKET, strerror(errno)); - return -1; - } - - while (1) - { - struct sockaddr addr; - socklen_t alen; - struct ucred cred; - socklen_t size; - - alen = sizeof(addr); - sFD = accept(socket, &addr, &alen); - if (sFD < 0) - continue; - - if (sDeferredUnmountableMediaPath) { - NotifyMediaState(sDeferredUnmountableMediaPath, MEDIA_UNMOUNTABLE, false); - free(sDeferredUnmountableMediaPath); - sDeferredUnmountableMediaPath = NULL; - } - - if (sAsecDeferredMessage) { - - if (Write2(sAsecDeferredMessage, sAsecDeferredArgument) < 0) - LOG_ERROR("Failed to deliver deferred ASEC msg to framework\n"); - free(sAsecDeferredMessage); - free(sAsecDeferredArgument); - sAsecDeferredMessage = sAsecDeferredArgument = NULL; - } - - while (1) - { - char buffer[101]; - int result = read(sFD, buffer, sizeof(buffer) - 1); - if (result > 0) - { - int start = 0; - int i; - // command should be zero terminated, but just in case - buffer[result] = 0; - for (i = 0; i < result; i++) - { - if (buffer[i] == 0) - { - DoCommand(buffer + start); - start = i + 1; - } - } - } - else - { - close(sFD); - sFD = -1; - break; - } - } - } - - // should never get here - return 0; -} - -void SendMassStorageConnected(boolean connected) -{ - Write(connected ? MOUNTD_UMS_CONNECTED : MOUNTD_UMS_DISCONNECTED); -} - -void SendUnmountRequest(const char* path) -{ - Write2(MOUNTD_REQUEST_EJECT, path); -} - -void NotifyAsecState(AsecState state, const char *argument) -{ - const char *event = NULL; - const char *status = NULL; - boolean deferr = true;; - - switch (state) { - case ASEC_DISABLED: - event = ASEC_EVENT_DISABLED; - status = ASEC_STATUS_DISABLED; - break; - case ASEC_AVAILABLE: - event = ASEC_EVENT_AVAILABLE; - status = ASEC_STATUS_AVAILABLE; - break; - case ASEC_BUSY: - event = ASEC_EVENT_BUSY; - status = ASEC_STATUS_BUSY; - deferr = false; - break; - case ASEC_FAILED_INTERR: - event = ASEC_EVENT_FAILED_INTERR; - status = ASEC_STATUS_FAILED_INTERR; - break; - case ASEC_FAILED_NOMEDIA: - event = ASEC_EVENT_FAILED_NOMEDIA; - status = ASEC_STATUS_FAILED_NOMEDIA; - break; - case ASEC_FAILED_BADMEDIA: - event = ASEC_EVENT_FAILED_BADMEDIA; - status = ASEC_STATUS_FAILED_BADMEDIA; - break; - case ASEC_FAILED_BADKEY: - event = ASEC_EVENT_FAILED_BADKEY; - status = ASEC_STATUS_FAILED_BADKEY; - break; - default: - LOG_ERROR("unknown AsecState %d in NotifyAsecState\n", state); - return; - } - - property_set(ASEC_STATUS, status); - - int result = Write2(event, argument); - if ((result < 0) && deferr) { - if (sAsecDeferredMessage) - free(sAsecDeferredMessage); - sAsecDeferredMessage = strdup(event); - if (sAsecDeferredArgument) - free(sAsecDeferredArgument); - sAsecDeferredArgument = strdup(argument); - LOG_ASEC("Deferring event '%s' arg '%s' until framework connects\n", event, argument); - } -} - -void NotifyMediaState(const char* path, MediaState state, boolean readOnly) -{ - const char* event = NULL; - const char* propertyValue = NULL; - - switch (state) { - case MEDIA_REMOVED: - event = MOUNTD_MEDIA_REMOVED; - propertyValue = EXTERNAL_STORAGE_REMOVED; - break; - case MEDIA_UNMOUNTED: - event = MOUNTD_MEDIA_UNMOUNTED; - propertyValue = EXTERNAL_STORAGE_UNMOUNTED; - break; - case MEDIA_MOUNTED: - event = (readOnly ? MOUNTD_MEDIA_MOUNTED_READ_ONLY : MOUNTD_MEDIA_MOUNTED); - propertyValue = (readOnly ? EXTERNAL_STORAGE_MOUNTED_READ_ONLY : EXTERNAL_STORAGE_MOUNTED); - break; - case MEDIA_SHARED: - event = MOUNTD_MEDIA_SHARED; - propertyValue = EXTERNAL_STORAGE_SHARED; - break; - case MEDIA_BAD_REMOVAL: - event = MOUNTD_MEDIA_BAD_REMOVAL; - propertyValue = EXTERNAL_STORAGE_BAD_REMOVAL; - break; - case MEDIA_UNMOUNTABLE: - event = MOUNTD_MEDIA_UNMOUNTABLE; - propertyValue = EXTERNAL_STORAGE_UNMOUNTABLE; - break; - default: - LOG_ERROR("unknown MediaState %d in NotifyMediaState\n", state); - return; - } - - property_set(EXTERNAL_STORAGE_STATE, propertyValue); - int result = Write2(event, path); - if (result < 0 && state == MEDIA_UNMOUNTABLE) { - - // if we cannot communicate with the runtime, defer this message until the runtime is available - sDeferredUnmountableMediaPath = strdup(path); - } -} diff --git a/mountd/logwrapper.c b/mountd/logwrapper.c deleted file mode 100644 index 69606ab62b9249d83ef8a8413712def2f9e8ca19..0000000000000000000000000000000000000000 --- a/mountd/logwrapper.c +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> - -#include "private/android_filesystem_config.h" -#include "cutils/log.h" - -int parent(const char *tag, int parent_read) { - int status; - char buffer[4096]; - - int a = 0; // start index of unprocessed data - int b = 0; // end index of unprocessed data - int sz; - while ((sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b)) > 0) { - - sz += b; - // Log one line at a time - for (b = 0; b < sz; b++) { - if (buffer[b] == '\r') { - buffer[b] = '\0'; - } else if (buffer[b] == '\n') { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - a = b + 1; - } - } - - if (a == 0 && b == sizeof(buffer) - 1) { - // buffer is full, flush - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - b = 0; - } else if (a != b) { - // Keep left-overs - b -= a; - memmove(buffer, &buffer[a], b); - a = 0; - } else { - a = 0; - b = 0; - } - - } - // Flush remaining data - if (a != b) { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - } - status = 0xAAAA; - if (wait(&status) != -1) { // Wait for child - if (WIFEXITED(status)) { - LOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", tag, - WEXITSTATUS(status)); - return WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) - LOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", tag, - WTERMSIG(status)); - else if (WIFSTOPPED(status)) - LOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", tag, - WSTOPSIG(status)); - } else - LOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag, - strerror(errno), errno); - return -EAGAIN; -} - -void child(int argc, char* argv[]) { - // create null terminated argv_child array - char* argv_child[argc + 1]; - memcpy(argv_child, argv, argc * sizeof(char *)); - argv_child[argc] = NULL; - - // XXX: PROTECT FROM VIKING KILLER - if (execvp(argv_child[0], argv_child)) { - LOG(LOG_ERROR, "logwrapper", - "executing %s failed: %s\n", argv_child[0], strerror(errno)); - exit(-1); - } -} - -int logwrap(int argc, char* argv[]) -{ - pid_t pid; - - int parent_ptty; - int child_ptty; - char *child_devname = NULL; - - /* Use ptty instead of socketpair so that STDOUT is not buffered */ - parent_ptty = open("/dev/ptmx", O_RDWR); - if (parent_ptty < 0) { - LOG(LOG_ERROR, "logwrapper", "Cannot create parent ptty\n"); - return -errno; - } - - if (grantpt(parent_ptty) || unlockpt(parent_ptty) || - ((child_devname = (char*)ptsname(parent_ptty)) == 0)) { - LOG(LOG_ERROR, "logwrapper", "Problem with /dev/ptmx\n"); - return -1; - } - - pid = fork(); - if (pid < 0) { - LOG(LOG_ERROR, "logwrapper", "Failed to fork\n"); - return -errno; - } else if (pid == 0) { - child_ptty = open(child_devname, O_RDWR); - if (child_ptty < 0) { - LOG(LOG_ERROR, "logwrapper", "Problem with child ptty\n"); - return -errno; - } - - // redirect stdout and stderr - close(parent_ptty); - dup2(child_ptty, 1); - dup2(child_ptty, 2); - close(child_ptty); - - child(argc, argv); - } else { - // switch user and group to "log" - // this may fail if we are not root, - // but in that case switching user/group is unnecessary - - // setgid(AID_LOG); - // setuid(AID_LOG); - - return parent(argv[0], parent_ptty); - } - - return 0; -} diff --git a/mountd/mountd.c b/mountd/mountd.c deleted file mode 100644 index 27ec8de90a3456cde8dea9e9515a5d969c28fff5..0000000000000000000000000000000000000000 --- a/mountd/mountd.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** mountd main program -*/ - -#include "mountd.h" - -#include <cutils/config_utils.h> -#include <cutils/cpu_info.h> -#include <cutils/properties.h> - -#include <sys/mount.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <linux/capability.h> -#include <linux/prctl.h> - -#include <private/android_filesystem_config.h> - -#ifdef MOUNTD_LOG -FILE* logFile; -#endif - -struct asec_cfg { - const char *name; - const char *backing_file; - const char *size; - const char *mount_point; - const char *crypt; -}; - -static int ProcessAsecData(cnode *node, struct asec_cfg *stores, int idx) -{ - cnode *child = node->first_child; - const char *name = NULL; - const char *file = NULL; - const char *size = NULL; - const char *mp = NULL; - const char *crypt = NULL; - - LOG_ASEC("ProcessAsecData(%s, %p, %d)\n", node->name, stores, idx); - - while (child) { - if (!strcmp(child->name, "name")) - name = child->value; - else if (!strcmp(child->name, "backing_file")) - file = child->value; - else if (!strcmp(child->name, "size")) - size = child->value; - else if (!strcmp(child->name, "mount_point")) - mp = child->value; - else if (!strcmp(child->name, "crypt")) - crypt = child->value; - child = child->next; - } - - if (!name || !file || !size || !mp || !crypt) { - LOG_ERROR("Missing required token from config. Skipping ASEC volume\n"); - return -1; - } else if (idx == ASEC_STORES_MAX) { - LOG_ERROR("Maximum # of ASEC stores already defined\n"); - return -1; - } - - stores[idx].name = name; - stores[idx].backing_file = file; - stores[idx].size = size; - stores[idx].mount_point = mp; - stores[idx].crypt = crypt; - return ++idx; -} - -static void ReadConfigFile(const char* path) -{ - cnode* root = config_node("", ""); - cnode* node; - - config_load_file(root, path); - node = root->first_child; - - while (node) - { - if (strcmp(node->name, "mount") == 0) - { - const char* block_device = NULL; - const char* mount_point = NULL; - const char* driver_store_path = NULL; - boolean enable_ums = false; - cnode* child = node->first_child; - struct asec_cfg asec_stores[ASEC_STORES_MAX]; - int asec_idx = 0; - - memset(asec_stores, 0, sizeof(asec_stores)); - - while (child) - { - const char* name = child->name; - const char* value = child->value; - - if (!strncmp(name, "asec_", 5)) { - int rc = ProcessAsecData(child, asec_stores, asec_idx); - if (rc < 0) { - LOG_ERROR("Error processing ASEC cfg data\n"); - } else - asec_idx = rc; - } else if (strcmp(name, "block_device") == 0) - block_device = value; - else if (strcmp(name, "mount_point") == 0) - mount_point = value; - else if (strcmp(name, "driver_store_path") == 0) - driver_store_path = value; - else if (strcmp(name, "enable_ums") == 0 && - strcmp(value, "true") == 0) - enable_ums = true; - - child = child->next; - } - - // mount point and removable fields are optional - if (block_device && mount_point) - { - void *mp = AddMountPoint(block_device, mount_point, driver_store_path, enable_ums); - int i; - - for (i = 0; i < asec_idx; i++) { - AddAsecToMountPoint(mp, asec_stores[i].name, asec_stores[i].backing_file, - asec_stores[i].size, asec_stores[i].mount_point, - asec_stores[i].crypt); - } - } - } - - node = node->next; - } -} - -int main(int argc, char* argv[]) -{ - const char* configPath = "/system/etc/mountd.conf"; - int i; - - for (i = 1; i < argc; i++) - { - const char* arg = argv[i]; - - if (strcmp(arg, "-f") == 0) - { - if (i < argc - 1) - configPath = argv[++i]; - } - } - - ReadConfigFile(configPath); - StartAutoMounter(); - return RunServer(); -} diff --git a/mountd/mountd.h b/mountd/mountd.h deleted file mode 100644 index c4bc91df6ee5bfaffcff85b9f2230b03a0e7511b..0000000000000000000000000000000000000000 --- a/mountd/mountd.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef MOUNTD_H__ -#define MOUNTD_H__ - -#define LOG_TAG "mountd" -#include "cutils/log.h" - -#include "ASEC.h" - -typedef int boolean; -enum { - false = 0, - true = 1 -}; - -#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) - -// Set this for logging error messages -#define ENABLE_LOG_ERROR - -// set this to log automounter events -#define ENABLE_LOG_MOUNT - -// set this to log server events -//#define ENABLE_LOG_SERVER - -// set this to log ASEC events -#define ENABLE_LOG_ASEC - -#ifdef ENABLE_LOG_ERROR -#define LOG_ERROR(fmt, args...) \ - { LOGE(fmt , ## args); } -#else -#define LOG_ERROR(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_ERROR */ - -#ifdef ENABLE_LOG_MOUNT -#define LOG_MOUNT(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_MOUNT(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_MOUNT */ - -#ifdef ENABLE_LOG_SERVER -#define LOG_SERVER(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_SERVER(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_SERVER */ - -#ifdef ENABLE_LOG_ASEC -#define LOG_ASEC(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_ASEC(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_ASEC */ - - -typedef enum MediaState { - // no media in SD card slot - MEDIA_REMOVED, - - // media in SD card slot, but not mounted - MEDIA_UNMOUNTED, - - // media in SD card slot and mounted at its mount point - MEDIA_MOUNTED, - - // media in SD card slot, unmounted, and shared as a mass storage device - MEDIA_SHARED, - - // media was removed from SD card slot, but mount point was not unmounted - // this state is cleared after the mount point is unmounted - MEDIA_BAD_REMOVAL, - - // media in SD card slot could not be mounted (corrupt file system?) - MEDIA_UNMOUNTABLE, -} MediaState; - -// socket name for connecting to mountd -#define MOUNTD_SOCKET "mountd" - -// mountd commands -// these must match the corresponding strings in //device/java/android/android/os/UsbListener.java -#define MOUNTD_ENABLE_UMS "enable_ums" -#define MOUNTD_DISABLE_UMS "disable_ums" -#define MOUNTD_SEND_STATUS "send_status" - -// these commands should contain a mount point following the colon -#define MOUNTD_MOUNT_MEDIA "mount_media:" -#define MOUNTD_EJECT_MEDIA "eject_media:" - -// mountd events -// these must match the corresponding strings in //device/java/android/android/os/UsbListener.java -#define MOUNTD_UMS_ENABLED "ums_enabled" -#define MOUNTD_UMS_DISABLED "ums_disabled" -#define MOUNTD_UMS_CONNECTED "ums_connected" -#define MOUNTD_UMS_DISCONNECTED "ums_disconnected" - -// these events correspond to the states in the MediaState enum. -// a path to the mount point follows the colon. -#define MOUNTD_MEDIA_REMOVED "media_removed:" -#define MOUNTD_MEDIA_UNMOUNTED "media_unmounted:" -#define MOUNTD_MEDIA_MOUNTED "media_mounted:" -#define MOUNTD_MEDIA_MOUNTED_READ_ONLY "media_mounted_ro:" -#define MOUNTD_MEDIA_SHARED "media_shared:" -#define MOUNTD_MEDIA_BAD_REMOVAL "media_bad_removal:" -#define MOUNTD_MEDIA_UNMOUNTABLE "media_unmountable:" - -// this event sent to request unmount for media mount point -#define MOUNTD_REQUEST_EJECT "request_eject:" - -// system properties -// these must match the corresponding strings in //device/java/android/android/os/Environment.java -#define EXTERNAL_STORAGE_STATE "EXTERNAL_STORAGE_STATE" -#define EXTERNAL_STORAGE_REMOVED "removed" -#define EXTERNAL_STORAGE_UNMOUNTED "unmounted" -#define EXTERNAL_STORAGE_MOUNTED "mounted" -#define EXTERNAL_STORAGE_MOUNTED_READ_ONLY "mounted_ro" -#define EXTERNAL_STORAGE_SHARED "shared" -#define EXTERNAL_STORAGE_BAD_REMOVAL "bad_removal" -#define EXTERNAL_STORAGE_UNMOUNTABLE "unmountable" - -// AutoMount.c - -boolean IsMassStorageEnabled(); -boolean IsMassStorageConnected(); - -void MountMedia(const char* mountPoint); -void UnmountMedia(const char* mountPoint); -void EnableMassStorage(boolean enable); - -// call this before StartAutoMounter() to add a mount point to monitor -void *AddMountPoint(const char* device, const char* mountPoint, const char* driverStorePath, - boolean enableUms); - -int AddAsecToMountPoint(void *Mp, const char *name, const char *backing_file, - const char *size, const char *mount_point, const char *crypt); - -// start automounter thread -void StartAutoMounter(); - -// check /proc/mounts for mounted file systems, and notify mount or unmount for any that are in our automount list -void NotifyExistingMounts(); - - -// ASEC.c - -void *AsecInit(const char *Name, const char *SrcPath, const char *BackingFile, - const char *Size, const char *DstPath, const char *Crypt); -int AsecStart(void *Handle); -int AsecStop(void *Handle); -void AsecDeinit(void *Handle); -boolean AsecIsStarted(void *Handle); -const char *AsecMountPoint(void *Handle); - -// ProcessKiller.c - -void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, pid_t *excluded, int num_excluded); - -// logwrapper.c -int logwrap(int argc, char* argv[]); - -// Server.c - -int RunServer(); -void SendMassStorageConnected(boolean connected); -void SendUnmountRequest(const char* path); -void NotifyMediaState(const char* path, MediaState state, boolean readOnly); -void NotifyAsecState(AsecState state, const char *argument); -#endif // MOUNTD_H__ diff --git a/netcfg/Android.mk b/netcfg/Android.mk deleted file mode 100644 index 949f4172822535be968fa480771afd1a719a25c2..0000000000000000000000000000000000000000 --- a/netcfg/Android.mk +++ /dev/null @@ -1,16 +0,0 @@ -ifneq ($(BUILD_TINY_ANDROID),true) -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) -LOCAL_SRC_FILES:= netcfg.c -LOCAL_MODULE:= netcfg - -#LOCAL_FORCE_STATIC_EXECUTABLE := true -#LOCAL_MODULE_PATH := $(TARGET_ROOT_OUT_SBIN) -#LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_SBIN_UNSTRIPPED) -#LOCAL_STATIC_LIBRARIES := libcutils libc - -LOCAL_SHARED_LIBRARIES := libc libnetutils - -include $(BUILD_EXECUTABLE) -endif diff --git a/netcfg/MODULE_LICENSE_APACHE2 b/netcfg/MODULE_LICENSE_APACHE2 deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/netcfg/NOTICE b/netcfg/NOTICE deleted file mode 100644 index c5b1efa7aac764ae6d8da63476a2d5cec02a6a5d..0000000000000000000000000000000000000000 --- a/netcfg/NOTICE +++ /dev/null @@ -1,190 +0,0 @@ - - Copyright (c) 2005-2008, The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/netcfg/netcfg.c b/netcfg/netcfg.c deleted file mode 100644 index fc9cf48b04113468c0ca7334d9d6e92c6c655305..0000000000000000000000000000000000000000 --- a/netcfg/netcfg.c +++ /dev/null @@ -1,175 +0,0 @@ -/* system/bin/netcfg/netcfg.c -** -** Copyright 2006, The Android Open Source Project -** -** Licensed under the Apache License, Version 2.0 (the "License"); -** you may not use this file except in compliance with the License. -** You may obtain a copy of the License at -** -** http://www.apache.org/licenses/LICENSE-2.0 -** -** Unless required by applicable law or agreed to in writing, software -** distributed under the License is distributed on an "AS IS" BASIS, -** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -** See the License for the specific language governing permissions and -** limitations under the License. -*/ - -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> -#include <dirent.h> - -static int verbose = 0; - -int ifc_init(); -void ifc_close(); -int ifc_up(char *iname); -int ifc_down(char *iname); -int ifc_remove_host_routes(char *iname); -int ifc_remove_default_route(char *iname); -int ifc_get_info(const char *name, unsigned *addr, unsigned *mask, unsigned *flags); -int do_dhcp(char *iname); - -void die(const char *reason) -{ - perror(reason); - exit(1); -} - -const char *ipaddr(unsigned addr) -{ - static char buf[32]; - - sprintf(buf,"%d.%d.%d.%d", - addr & 255, - ((addr >> 8) & 255), - ((addr >> 16) & 255), - (addr >> 24)); - return buf; -} - -void usage(void) -{ - fprintf(stderr,"usage: netcfg [<interface> {dhcp|up|down}]\n"); - exit(1); -} - -int dump_interface(const char *name) -{ - unsigned addr, mask, flags; - - if(ifc_get_info(name, &addr, &mask, &flags)) { - return 0; - } - - printf("%-8s %s ", name, flags & 1 ? "UP " : "DOWN"); - printf("%-16s", ipaddr(addr)); - printf("%-16s", ipaddr(mask)); - printf("0x%08x\n", flags); - return 0; -} - -int dump_interfaces(void) -{ - DIR *d; - struct dirent *de; - - d = opendir("/sys/class/net"); - if(d == 0) return -1; - - while((de = readdir(d))) { - if(de->d_name[0] == '.') continue; - dump_interface(de->d_name); - } - closedir(d); - return 0; -} - -struct -{ - const char *name; - int nargs; - void *func; -} CMDS[] = { - { "dhcp", 1, do_dhcp }, - { "up", 1, ifc_up }, - { "down", 1, ifc_down }, - { "flhosts", 1, ifc_remove_host_routes }, - { "deldefault", 1, ifc_remove_default_route }, - { 0, 0, 0 }, -}; - -static int call_func(void *_func, unsigned nargs, char **args) -{ - switch(nargs){ - case 1: { - int (*func)(char *a0) = _func; - return func(args[0]); - } - case 2: { - int (*func)(char *a0, char *a1) = _func; - return func(args[0], args[1]); - } - case 3: { - int (*func)(char *a0, char *a1, char *a2) = _func; - return func(args[0], args[1], args[2]); - } - default: - return -1; - } -} - -int main(int argc, char **argv) -{ - char *iname; - int n; - - if(ifc_init()) { - die("Cannot perform requested operation"); - } - - if(argc == 1) { - int result = dump_interfaces(); - ifc_close(); - return result; - } - - if(argc < 3) usage(); - - iname = argv[1]; - if(strlen(iname) > 16) usage(); - - argc -= 2; - argv += 2; - while(argc > 0) { - for(n = 0; CMDS[n].name; n++){ - if(!strcmp(argv[0], CMDS[n].name)) { - char *cmdname = argv[0]; - int nargs = CMDS[n].nargs; - - argv[0] = iname; - if(argc < nargs) { - fprintf(stderr, "not enough arguments for '%s'\n", cmdname); - ifc_close(); - exit(1); - } - if(call_func(CMDS[n].func, nargs, argv)) { - fprintf(stderr, "action '%s' failed (%s)\n", cmdname, strerror(errno)); - ifc_close(); - exit(1); - } - argc -= nargs; - argv += nargs; - goto done; - } - } - fprintf(stderr,"no such action '%s'\n", argv[0]); - usage(); - done: - ; - } - ifc_close(); - - return 0; -} diff --git a/rootdir/Android.mk b/rootdir/Android.mk deleted file mode 100644 index b2fe8cf15266ddadc5132037ce3e4272fa90301d..0000000000000000000000000000000000000000 --- a/rootdir/Android.mk +++ /dev/null @@ -1,58 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -# files that live under /system/etc/... - -copy_from := \ - etc/dbus.conf \ - etc/init.goldfish.sh \ - etc/hosts - -dont_copy := \ - etc/init.gprs-pppd \ - etc/ppp/chap-secrets \ - etc/ppp/ip-down \ - etc/ppp/ip-up - -copy_to := $(addprefix $(TARGET_OUT)/,$(copy_from)) -copy_from := $(addprefix $(LOCAL_PATH)/,$(copy_from)) - -$(copy_to) : PRIVATE_MODULE := system_etcdir -$(copy_to) : $(TARGET_OUT)/% : $(LOCAL_PATH)/% | $(ACP) - $(transform-prebuilt-to-target) - -ALL_PREBUILT += $(copy_to) - - -# files that live under /... - -# Only copy init.rc if the target doesn't have its own. -ifneq ($(TARGET_PROVIDES_INIT_RC),true) -file := $(TARGET_ROOT_OUT)/init.rc -$(file) : $(LOCAL_PATH)/init.rc | $(ACP) - $(transform-prebuilt-to-target) -ALL_PREBUILT += $(file) -endif - -file := $(TARGET_ROOT_OUT)/init.goldfish.rc -$(file) : $(LOCAL_PATH)/etc/init.goldfish.rc | $(ACP) - $(transform-prebuilt-to-target) -ALL_PREBUILT += $(file) - - -# create some directories (some are mount points) -DIRS := $(addprefix $(TARGET_ROOT_OUT)/, \ - sbin \ - dev \ - proc \ - sys \ - system \ - data \ - ) \ - $(TARGET_OUT_DATA) - -$(DIRS): - @echo Directory: $@ - @mkdir -p $@ - -ALL_PREBUILT += $(DIRS) diff --git a/rootdir/etc/dbus.conf b/rootdir/etc/dbus.conf deleted file mode 100644 index 75586b92dc6cfec6863362659d21157a6f2f8591..0000000000000000000000000000000000000000 --- a/rootdir/etc/dbus.conf +++ /dev/null @@ -1,27 +0,0 @@ -<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" - "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> -<busconfig> - - <!-- Our well-known bus type, do not change this --> - <type>system</type> - - <!-- Only allow socket-credentials-based authentication --> - <auth>EXTERNAL</auth> - - <!-- Only listen on a local socket. (abstract=/path/to/socket - means use abstract namespace, don't really create filesystem - file; only Linux supports this. Use path=/whatever on other - systems.) --> - <listen>unix:path=/dev/socket/dbus</listen> - - <!-- Allow everything, D-Bus socket is protected by unix filesystem - permissions --> - <policy context="default"> - <allow send_interface="*"/> - <allow receive_interface="*"/> - <allow own="*"/> - <allow user="*"/> - <allow send_requested_reply="true"/> - <allow receive_requested_reply="true"/> - </policy> -</busconfig> diff --git a/rootdir/etc/hosts b/rootdir/etc/hosts deleted file mode 100644 index 99848f6431bb64706eff0125c388c3f3212e380c..0000000000000000000000000000000000000000 --- a/rootdir/etc/hosts +++ /dev/null @@ -1 +0,0 @@ -127.0.0.1 localhost diff --git a/rootdir/etc/init.goldfish.rc b/rootdir/etc/init.goldfish.rc deleted file mode 100644 index 96480f3e87d9089869664e797fd4cdaaae1d001e..0000000000000000000000000000000000000000 --- a/rootdir/etc/init.goldfish.rc +++ /dev/null @@ -1,54 +0,0 @@ -on boot - setprop ARGH ARGH - setprop net.eth0.dns1 10.0.2.3 - setprop net.gprs.local-ip 10.0.2.15 - setprop ro.radio.use-ppp no - setprop ro.build.product generic - setprop ro.product.device generic - -# fake some battery state - setprop status.battery.state Slow - setprop status.battery.level 5 - setprop status.battery.level_raw 50 - setprop status.battery.level_scale 9 - -# disable some daemons the emulator doesn't want - stop dund - stop akmd - - setprop ro.setupwizard.mode EMULATOR - -# enable Google-specific location features, -# like NetworkLocationProvider and LocationCollector - setprop ro.com.google.locationfeatures 1 - -# For the emulator, which bypasses Setup Wizard, you can specify -# account info for the device via these two properties. Google -# Login Service will insert these accounts into the database when -# it is created (ie, after a data wipe). -# -# setprop ro.config.hosted_account username@hosteddomain.org:password -# setprop ro.config.google_account username@gmail.com:password -# -# You MUST have a Google account on the device, and you MAY -# additionally have a hosted account. No other configuration is -# supported, and arbitrary breakage may result if you specify -# something else. - -service goldfish-setup /system/etc/init.goldfish.sh - oneshot - -service qemud /system/bin/qemud - socket qemud_gsm stream 666 - socket qemud_gps stream 666 - socket qemud_control stream 666 - oneshot - -# -Q is a special logcat option that forces the -# program to check wether it runs on the emulator -# if it does, it redirects its output to the device -# named by the androidboot.console kernel option -# if not, is simply exit immediately - -service goldfish-logcat /system/bin/logcat -Q - oneshot diff --git a/rootdir/etc/init.goldfish.sh b/rootdir/etc/init.goldfish.sh deleted file mode 100755 index 0eb0154bf5fadbe99dc5f8f91a8f8decf879c24b..0000000000000000000000000000000000000000 --- a/rootdir/etc/init.goldfish.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/system/bin/sh - -ifconfig eth0 10.0.2.15 netmask 255.255.255.0 up -route add default gw 10.0.2.2 dev eth0 - -qemud=`getprop.ro.kernel.android.qemud` -if test -z "$qemud"; then - radio_ril=`getprop ro.kernel.android.ril` - if test -z "$radio_ril"; then - # no need for the radio interface daemon - # telephony is entirely emulated in Java - setprop ro.radio.noril yes - stop ril-daemon - fi -fi - -num_dns=`getprop ro.kernel.android.ndns` -case "$num_dns" in - 2) setprop net.eth0.dns2 10.0.2.4 - ;; - 3) setprop net.eth0.dns2 10.0.2.4 - setprop net.eth0.dns3 10.0.2.5 - ;; - 4) setprop net.eth0.dns2 10.0.2.4 - setprop net.eth0.dns3 10.0.2.5 - setprop net.eth0.dns4 10.0.2.6 - ;; -esac - -# disable boot animation for a faster boot sequence when needed -boot_anim=`getprop ro.kernel.android.bootanim` -case "$boot_anim" in - 0) setprop debug.sf.nobootanimation 1 - ;; -esac - -# this line doesn't really do anything useful. however without it the -# previous setprop doesn't seem to apply for some really odd reason -setprop ro.qemu.init.completed 1 diff --git a/rootdir/etc/init.gprs-pppd b/rootdir/etc/init.gprs-pppd deleted file mode 100755 index 521eec9886318cac0459d8b63dd8a06786aa26f7..0000000000000000000000000000000000000000 --- a/rootdir/etc/init.gprs-pppd +++ /dev/null @@ -1,23 +0,0 @@ -#!/system/bin/sh -# An unforunate wrapper script -# so that the exit code of pppd may be retrieved - - -# this is a workaround for issue #651747 -#trap "/system/bin/sleep 1;exit 0" TERM - - -PPPD_PID= - -/system/bin/setprop "net.gprs.ppp-exit" "" - -/system/bin/log -t pppd "Starting pppd" - -/system/bin/pppd $* - -PPPD_EXIT=$? -PPPD_PID=$! - -/system/bin/log -t pppd "pppd exited with $PPPD_EXIT" - -/system/bin/setprop "net.gprs.ppp-exit" "$PPPD_EXIT" diff --git a/rootdir/etc/init.testmenu b/rootdir/etc/init.testmenu deleted file mode 100755 index 7ae16d501373b10c2db8605de60f34e46315056b..0000000000000000000000000000000000000000 --- a/rootdir/etc/init.testmenu +++ /dev/null @@ -1,322 +0,0 @@ -#!/system/bin/sh - -atdev=/dev/omap_csmi_tty0 -pppdev=/dev/omap_csmi_tty1 - -n1=`cat /data/phoneentry1 2>/dev/null` -n2=`cat /data/phoneentry2 2>/dev/null` -n3=`cat /data/phoneentry3 2>/dev/null` -n1=${n1:-"*#06#"} -n2=${n2:-"*#06#"} -n3=${n3:-"*#06#"} -phoneoutputpid= -eventoutputpid= -notifypid= -notifytoggle=false -pppdpid= -powerdidletime=120 - -# map phone specific keys -setkey -k 0xe4 -v 0x23 # map # -setkey -k 0xe3 -v 0x2a # map * -setkey -k 231 -v 513 # map send to newline -#setkey -k 0x67 -v 0x20b # map up to scroll back -#setkey -k 0x6c -v 0x20a # map down to scroll forward -setkey -k 0x73 -v 0x20b # map volume up to scroll back -setkey -k 0x72 -v 0x20a # map volume down to scroll forward -setkey -k 0x60 -v 0x211 # map PoC to next console - -# tuttle keys -setkey -k 0x38 -v 0x703 # map leftalt to alt -setkey -k 0x9b -v 0x703 # map mail to alt -setkey -t 8 -k 0x9b -v 0x703 # map alt-mail to alt -setkey -t 8 -k 0x10 -v 0x21 # map alt-q to ! -setkey -t 8 -k 0x11 -v 0x31 # map alt-w to 1 -setkey -t 8 -k 0x12 -v 0x32 # map alt-e to 2 -setkey -t 8 -k 0x13 -v 0x33 # map alt-r to 3 -setkey -t 8 -k 0x14 -v 0x2b # map alt-t to + -setkey -t 8 -k 0x15 -v 0x28 # map alt-y to ( -setkey -t 8 -k 0x16 -v 0x29 # map alt-u to ) -setkey -t 8 -k 0x17 -v 0x2d # map alt-i to - -setkey -t 8 -k 0x18 -v 0x5f # map alt-o to _ -setkey -t 8 -k 0x19 -v 0x22 # map alt-p to " -setkey -t 8 -k 0x1e -v 0x23 # map alt-a to # -setkey -t 8 -k 0x1f -v 0x34 # map alt-s to 4 -setkey -t 8 -k 0x20 -v 0x35 # map alt-d to 5 -setkey -t 8 -k 0x21 -v 0x36 # map alt-f to 6 -setkey -t 8 -k 0x22 -v 0x2f # map alt-g to / -setkey -t 8 -k 0x23 -v 0x3f # map alt-h to ? -setkey -t 8 -k 0x24 -v 0xa3 # map alt-j to pound -setkey -t 8 -k 0x25 -v 0x24 # map alt-k to $ -setkey -t 8 -k 0x2c -v 0x2a # map alt-z to * -setkey -t 8 -k 0x2d -v 0x37 # map alt-x to 7 -setkey -t 8 -k 0x2e -v 0x38 # map alt-c to 8 -setkey -t 8 -k 0x2f -v 0x39 # map alt-v to 9 -setkey -t 8 -k 0x30 -v 0x7c # map alt-b to | -setkey -t 8 -k 0x31 -v 0x40 # map alt-n to @ -setkey -t 8 -k 0x32 -v 0x3d # map alt-m to = -setkey -t 8 -k 0x33 -v 0x3b # map alt-, to ; -setkey -t 8 -k 0x34 -v 0x3a # map alt-. to : -setkey -t 8 -k 0x0f -v 0x30 # map alt-tab to 0 -setkey -t 8 -k 0x67 -v 0x20b # map alt-up to scroll back -setkey -t 8 -k 0x6c -v 0x20a # map alt-down to scroll forward - -while true -do - echo - echo "------------------------------" - echo " 1: init commands" - echo " 2: call commands" - echo " 3: misc phone" - echo " 4: phone debug output" - echo " 5: test data connection" - echo " 6: start runtime" - echo " 7: start runtime w/output" - echo " 8: stop runtime" - echo " 9: misc" - echo -n ": " - while true - do - c=`readtty -t 50 -f -a 1234567890#` - case "$c" in - "" ) ;; - * ) break; - esac - done - echo Got key -$c- - case $c in - "1" ) - while true; do - echo - echo "------------------------------" - echo " 1: Print phone output" - echo " 2: ATQ0V1E1+CMEE=2;+CREG=0" - echo " 3: AT+CFUN=1" - echo " 4: AT+COPS=0" - echo " 5: AT+CREG?" - echo " 6: Stop phone output" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 1234560#` - echo Got key -$c- - case "$c" in - "1" ) kill $phoneoutputpid; cat $atdev & phoneoutputpid=$! ;; - "2" ) echo -e "ATQ0V1E1+CMEE=2;+CREG=0\r" >$atdev;; - "3" ) echo -e "AT+CFUN=1\r" >$atdev;; - "4" ) echo -e "AT+COPS=0\r" >$atdev;; - "5" ) echo -e "AT+CREG?\r" >$atdev;; - "6" ) kill $phoneoutputpid; phoneoutputpid= ;; - "0" ) break;; - esac - done - ;; - "2" ) - while true; do - echo - echo "------------------------------" - echo " 1: Dial: ATD $n1;" - echo " 2: Dial: ATD $n2;" - echo " 3: Dial: ATD $n3;" - echo " 4: Set number for 1" - echo " 5: Set number for 2" - echo " 6: Set number for 3" - echo " 7: Dial: ATD ...;" - echo " 8: Hang up: ATH" - echo " 9: Answer: ATA" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 1234567890#` - echo Got key -$c- - case "$c" in - "1" ) echo "Dialing $n1"; echo -e "ATD $n1;\r" >$atdev;; - "2" ) echo "Dialing $n2"; echo -e "ATD $n2;\r" >$atdev;; - "3" ) echo "Dialing $n3"; echo -e "ATD $n3;\r" >$atdev;; - "4" ) echo -n "Number: "; read n1; echo $n1 >/data/phoneentry1;; - "5" ) echo -n "Number: "; read n2; echo $n2 >/data/phoneentry2;; - "6" ) echo -n "Number: "; read n3; echo $n3 >/data/phoneentry3;; - "7" ) echo -n "Number: "; read n; echo "Dialing $n"; echo -e "ATD $n;\r" >$atdev;; - "8" ) echo -e "ATH\r" >$atdev;; - "9" ) echo -e "ATA\r" >$atdev;; - "0" ) break;; - esac - done - ;; - "3" ) - while true; do - echo - echo "------------------------------" - echo " 1: Save FFS data" - echo " 2: Load user FFS data" - echo " 3: Load system FFS data" - echo " 4: Reset FFS data" - echo " 5: Set uplink gain" - echo " 6: Set echo" - echo " 7: cat /dev/omap_csmi_battery_t" - echo " 8: cat /dev/omap_csmi_htc" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 123456780#` - echo Got key -$c- - case "$c" in - "1" ) cat /dev/omap_csmi_ffs >/data/ffsdata;; - "2" ) cat /data/ffsdata >/dev/omap_csmi_ffs;; - "3" ) cat /system/ffsdata >/dev/omap_csmi_ffs;; - "4" ) echo - >/dev/omap_csmi_ffs;; - "5" ) - echo -n "Gain: "; read g; - echo gu$g >/tmp/gain; - cat /tmp/gain 2>/dev/null >/dev/omap_csmi_audio_tes - ;; - "6" ) - echo -n "Echo param (hex): "; read e; - echo "e0x$e" >/tmp/echo; - cat /tmp/echo 2>/dev/null >/dev/omap_csmi_audio_tes - ;; - "7" ) cat /dev/omap_csmi_battery_t;; - "8" ) cat /dev/omap_csmi_htc;; - "0" ) break;; - esac - done - ;; - "4" ) - while true; do - echo - echo "------------------------------" - echo " 1: Toggle debug I/O" - echo " 2: Toggle debug Flow" - echo " 3: Toggle debug Interrupt" - echo " 4: Toggle debug Info" - echo " 5: Toggle GSM run state" - echo " 6: Clear GSM data area" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 1234560#` - echo Got key -$c- - case "$c" in - "1" ) echo -n "i" >/sys/devices/system/omap_csmi/debug;; - "2" ) echo -n "f" >/sys/devices/system/omap_csmi/debug;; - "3" ) echo -n "I" >/sys/devices/system/omap_csmi/debug;; - "4" ) echo -n "F" >/sys/devices/system/omap_csmi/debug;; - "5" ) echo -n "s" >/sys/devices/system/omap_csmi/debug;; - "6" ) echo -n "c" >/sys/devices/system/omap_csmi/debug;; - "0" ) break;; - esac - done - ;; - "5" ) - while true; do - echo - echo "------------------------------" - echo " 1: Start pppd - userspace" - echo " 2: Start pppd - kernel" - echo " 3: Start pppd - kernel <at1" - echo " 4: Configure ppp data to at2" - echo " 5: Test with HTTP GET" - echo " 6: Kill pppd" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 1234560#` - echo Got key -$c- - case "$c" in - "1" ) kill $pppdpid; pppd notty < $pppdev > $pppdev & pppdpid=$!;; - "2" ) kill $pppdpid; pppd nodetach $pppdev & pppdpid=$!;; - "3" ) kill &pppdpid; pppd nodetach $pppdev connect "sh -c \"chat -v -f /etc/ppp/connect-data <$atdev >$atdev\"" & pppdpid=$!;; - "4" ) echo -e 'AT%DATA=2,"UART",1,,"SER","UART",0\r' >$atdev;; - "5" ) test-data-connection;; - "6" ) kill $pppdpid; pppdpid=;; - "0" ) break;; - esac - done - ;; - "6" ) - echo - echo ------------------------ - echo Starting android runtime - echo ------------------------ - start - ;; - "7" ) - echo - echo ------------------------ - echo Starting android runtime - echo ------------------------ - if exists /data/singleproc - then - single_process="-s" - else - single_process="" - fi - start runtime $single_process - ;; - "8" ) - stop - ;; - "9" ) - while true; do - echo - echo "------------------------------" - echo " 1: Print events" - echo " 2: Stop event output" - if $notifytoggle - then - echo " 3: stop notify" - else - echo " 3: notify /sys/android_power" - fi - echo " 4: start powerd" - echo " 5: start powerd verbose" - echo " 6: stop powerd" - echo " 7: set powerd idletime ($powerdidletime)" - echo " 8: start multitap shell" - if exists /data/singleproc - then - echo " 9: enable multiprocess" - else - echo " 9: disable multiprocess" - fi - echo " c: start shell" - echo " 0: back" - echo -n ": " - c=`readtty -f -a 1234567890c#` - echo Got key -$c- - case "$c" in - "1" ) kill $eventoutputpid; getevent & eventoutputpid=$! ;; - "2" ) kill $eventoutputpid; eventoutputpid= ;; - "3" ) - if $notifytoggle - then - kill $notifypid - notifypid= - notifytoggle=false - else - kill $notifypid - notify -m 0x00000002 -c 0 -p -v 0 -w 30 /sys/android_power & - notifypid=$! - notifytoggle=true - fi - ;; - "4" ) start powerd -i $powerdidletime ;; - "5" ) start powerd -i $powerdidletime -v ;; - "6" ) stop powerd ;; - "7" ) echo -n "Idle time (seconds): "; read powerdidletime ;; - "8" ) - readtty -f -p -t 10 -e "[ ~" | sh -i - ;; - "9" ) - if exists /data/singleproc - then - echo "Enabling multiprocess environment." - rm /data/singleproc - else - echo "Disabling multiprocess environment." - echo >/data/singleproc "true" - fi - ;; - "c" ) sh -i <>/dev/tty0 1>&0 2>&1 ;; - "0" ) break;; - esac - done - ;; - esac -done - diff --git a/rootdir/etc/mountd.conf b/rootdir/etc/mountd.conf deleted file mode 100644 index 094a2c7af0a5e3a935dce7d0cb298c2a978887c9..0000000000000000000000000000000000000000 --- a/rootdir/etc/mountd.conf +++ /dev/null @@ -1,19 +0,0 @@ -## mountd configuration file - -## add a mount entry for each mount point to be managed by mountd -mount { - ## root block device with partition map or raw FAT file system - block_device /dev/block/mmcblk0 - - ## mount point for block device - mount_point /sdcard - - ## true if this mount point can be shared via USB mass storage - enable_ums true - - ## path to the UMS driver file for specifying the block device path - ## use this for the mass_storage function driver - driver_store_path /sys/devices/platform/usb_mass_storage/lun0/file - ## use this for android_usb composite gadget driver - ##driver_store_path /sys/devices/platform/msm_hsusb/gadget/lun0/file -} diff --git a/rootdir/etc/ppp/chap-secrets b/rootdir/etc/ppp/chap-secrets deleted file mode 100644 index 6546b0f1c2c85bfe8e7735aafa545e4580a453ec..0000000000000000000000000000000000000000 --- a/rootdir/etc/ppp/chap-secrets +++ /dev/null @@ -1,2 +0,0 @@ -* * bogus - diff --git a/rootdir/etc/ppp/ip-down b/rootdir/etc/ppp/ip-down deleted file mode 100755 index 672fa1e749b9d0662f3f84988e079e45d3f2b3b2..0000000000000000000000000000000000000000 --- a/rootdir/etc/ppp/ip-down +++ /dev/null @@ -1,14 +0,0 @@ -#!/system/bin/sh -case $1 in - ppp1) - echo 0 > /proc/sys/net/ipv4/ip_forward; - ;; -esac - -# Use interface name if linkname is not available -NAME=${LINKNAME:-"$1"} - -/system/bin/setprop "net.$NAME.dns1" "$DNS1" -/system/bin/setprop "net.$NAME.dns2" "$DNS2" -/system/bin/setprop "net.$NAME.local-ip" "$IPLOCAL" -/system/bin/setprop "net.$NAME.remote-ip" "$IPREMOTE" diff --git a/rootdir/etc/ppp/ip-up b/rootdir/etc/ppp/ip-up deleted file mode 100755 index cb2d577856c50a3c2acdc5e44c107ed3f1bd60e1..0000000000000000000000000000000000000000 --- a/rootdir/etc/ppp/ip-up +++ /dev/null @@ -1,24 +0,0 @@ -#!/system/bin/sh -case $1 in - ppp1) - /android/bin/iptables --flush; - /android/bin/iptables --table nat --flush; - /android/bin/iptables --delete-chain; - /android/bin/iptables --table nat --append POSTROUTING --out-interface ppp0 -j MASQUERADE; - /android/bin/iptables --append FORWARD --in-interface ppp1 -j ACCEPT; - echo 0 > /proc/sys/net/ipv4/ip_forward; - echo 1 > /proc/sys/net/ipv4/ip_forward; - ;; - ppp0) - /system/bin/setprop "net.interfaces.defaultroute" "gprs" - ;; -esac - -# Use interface name if linkname is not available -NAME=${LINKNAME:-"$1"} - -/system/bin/setprop "net.$NAME.dns1" "$DNS1" -/system/bin/setprop "net.$NAME.dns2" "$DNS2" -/system/bin/setprop "net.$NAME.local-ip" "$IPLOCAL" -/system/bin/setprop "net.$NAME.remote-ip" "$IPREMOTE" - diff --git a/rootdir/init.rc b/rootdir/init.rc deleted file mode 100644 index 3f8c6a01bed63dc336f18afaec417d6ffcf546ce..0000000000000000000000000000000000000000 --- a/rootdir/init.rc +++ /dev/null @@ -1,245 +0,0 @@ - -on init - -sysclktz 0 - -loglevel 3 - -# setup the global environment - export PATH /sbin:/system/sbin:/system/bin:/system/xbin - export LD_LIBRARY_PATH /system/lib - export ANDROID_BOOTLOGO 1 - export ANDROID_ROOT /system - export ANDROID_ASSETS /system/app - export ANDROID_DATA /data - export EXTERNAL_STORAGE /sdcard - export BOOTCLASSPATH /system/framework/core.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/android.policy.jar:/system/framework/services.jar - -# Backward compatibility - symlink /system/etc /etc - -# create mountpoints and mount tmpfs on sqlite_stmt_journals - mkdir /sdcard 0000 system system - mkdir /system - mkdir /data 0771 system system - mkdir /cache 0770 system cache - mkdir /sqlite_stmt_journals 01777 root root - mount tmpfs tmpfs /sqlite_stmt_journals size=4m - - mount rootfs rootfs / ro remount - - write /proc/sys/kernel/panic_on_oops 1 - write /proc/sys/kernel/hung_task_timeout_secs 0 - write /proc/cpu/alignment 4 - write /proc/sys/kernel/sched_latency_ns 10000000 - write /proc/sys/kernel/sched_wakeup_granularity_ns 2000000 - -# mount mtd partitions - # Mount /system rw first to give the filesystem a chance to save a checkpoint - mount yaffs2 mtd@system /system - mount yaffs2 mtd@system /system ro remount - - # We chown/chmod /data again so because mount is run as root + defaults - mount yaffs2 mtd@userdata /data nosuid nodev - chown system system /data - chmod 0771 /data - - # Same reason as /data above - mount yaffs2 mtd@cache /cache nosuid nodev - chown system cache /cache - chmod 0770 /cache - - # This may have been created by the recovery system with odd permissions - chown system system /cache/recovery - chmod 0770 /cache/recovery - -# create basic filesystem structure - mkdir /data/misc 01771 system misc - mkdir /data/misc/hcid 0770 bluetooth bluetooth - mkdir /data/local 0771 shell shell - mkdir /data/local/tmp 0771 shell shell - mkdir /data/data 0771 system system - mkdir /data/app-private 0771 system system - mkdir /data/app 0771 system system - mkdir /data/property 0700 root root - - # create dalvik-cache and double-check the perms - mkdir /data/dalvik-cache 0771 system system - chown system system /data/dalvik-cache - chmod 0771 /data/dalvik-cache - - # create the lost+found directories, so as to enforce our permissions - mkdir /data/lost+found 0770 - mkdir /cache/lost+found 0770 - - # double check the perms, in case lost+found already exists, and set owner - chown root root /data/lost+found - chmod 0770 /data/lost+found - chown root root /cache/lost+found - chmod 0770 /cache/lost+found - -on boot -# basic network init - ifup lo - hostname localhost - domainname localdomain - -# set RLIMIT_NICE to allow priorities from 19 to -20 - setrlimit 13 40 40 - -# Define the oom_adj values for the classes of processes that can be -# killed by the kernel. These are used in ActivityManagerService. - setprop ro.FOREGROUND_APP_ADJ 0 - setprop ro.VISIBLE_APP_ADJ 1 - setprop ro.SECONDARY_SERVER_ADJ 2 - setprop ro.HIDDEN_APP_MIN_ADJ 7 - setprop ro.CONTENT_PROVIDER_ADJ 14 - setprop ro.EMPTY_APP_ADJ 15 - -# Define the memory thresholds at which the above process classes will -# be killed. These numbers are in pages (4k). - setprop ro.FOREGROUND_APP_MEM 1536 - setprop ro.VISIBLE_APP_MEM 2048 - setprop ro.SECONDARY_SERVER_MEM 4096 - setprop ro.HIDDEN_APP_MEM 5120 - setprop ro.CONTENT_PROVIDER_MEM 5632 - setprop ro.EMPTY_APP_MEM 6144 - -# Write value must be consistent with the above properties. - write /sys/module/lowmemorykiller/parameters/adj 0,1,2,7,14,15 - - write /proc/sys/vm/overcommit_memory 1 - write /sys/module/lowmemorykiller/parameters/minfree 1536,2048,4096,5120,5632,6144 - - # Set init its forked children's oom_adj. - write /proc/1/oom_adj -16 - - # Permissions for System Server and daemons. - chown radio system /sys/android_power/state - chown radio system /sys/android_power/request_state - chown radio system /sys/android_power/acquire_full_wake_lock - chown radio system /sys/android_power/acquire_partial_wake_lock - chown radio system /sys/android_power/release_wake_lock - chown radio system /sys/power/state - chown radio system /sys/power/wake_lock - chown radio system /sys/power/wake_unlock - chmod 0660 /sys/power/state - chmod 0660 /sys/power/wake_lock - chmod 0660 /sys/power/wake_unlock - chown system system /sys/class/timed_output/vibrator/enable - chown system system /sys/class/leds/keyboard-backlight/brightness - chown system system /sys/class/leds/lcd-backlight/brightness - chown system system /sys/class/leds/button-backlight/brightness - chown system system /sys/class/leds/red/brightness - chown system system /sys/class/leds/green/brightness - chown system system /sys/class/leds/blue/brightness - chown system system /sys/class/leds/red/device/grpfreq - chown system system /sys/class/leds/red/device/grppwm - chown system system /sys/class/leds/red/device/blink - chown system system /sys/class/leds/red/brightness - chown system system /sys/class/leds/green/brightness - chown system system /sys/class/leds/blue/brightness - chown system system /sys/class/leds/red/device/grpfreq - chown system system /sys/class/leds/red/device/grppwm - chown system system /sys/class/leds/red/device/blink - chown system system /sys/class/timed_output/vibrator/enable - chown system system /sys/module/sco/parameters/disable_esco - chown system system /sys/kernel/ipv4/tcp_wmem_min - chown system system /sys/kernel/ipv4/tcp_wmem_def - chown system system /sys/kernel/ipv4/tcp_wmem_max - chown system system /sys/kernel/ipv4/tcp_rmem_min - chown system system /sys/kernel/ipv4/tcp_rmem_def - chown system system /sys/kernel/ipv4/tcp_rmem_max - chown root radio /proc/cmdline - -# Define TCP buffer sizes for various networks -# ReadMin, ReadInitial, ReadMax, WriteMin, WriteInitial, WriteMax, - setprop net.tcp.buffersize.default 4096,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.wifi 4095,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.umts 4094,87380,110208,4096,16384,110208 - setprop net.tcp.buffersize.edge 4093,26280,35040,4096,16384,35040 - setprop net.tcp.buffersize.gprs 4092,8760,11680,4096,8760,11680 - - class_start default - -## Daemon processes to be run by init. -## -service console /system/bin/sh - console - -# adbd is controlled by the persist.service.adb.enable system property -service adbd /sbin/adbd - disabled - -# adbd on at boot in emulator -on property:ro.kernel.qemu=1 - start adbd - -on property:persist.service.adb.enable=1 - start adbd - -on property:persist.service.adb.enable=0 - stop adbd - -service servicemanager /system/bin/servicemanager - user system - critical - onrestart restart zygote - onrestart restart media - -service mountd /system/bin/mountd - socket mountd stream 0660 root mount - -service debuggerd /system/bin/debuggerd - -service ril-daemon /system/bin/rild - socket rild stream 660 root radio - socket rild-debug stream 660 radio system - user root - group radio cache inet misc - -service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server - socket zygote stream 666 - onrestart write /sys/android_power/request_state wake - onrestart write /sys/power/state on - -service media /system/bin/mediaserver - user media - group system audio camera graphics inet net_bt net_bt_admin - -service bootsound /system/bin/playmp3 - user media - group audio - oneshot - -service dbus /system/bin/dbus-daemon --system --nofork - socket dbus stream 660 bluetooth bluetooth - user bluetooth - group bluetooth net_bt_admin - -#STOPSHIP: disable the verbose logging -service hcid /system/bin/logwrapper /system/bin/hcid -d -s -n -f /etc/bluez/hcid.conf - socket bluetooth stream 660 bluetooth bluetooth - socket dbus_bluetooth stream 660 bluetooth bluetooth - # init.rc does not yet support applying capabilities, so run as root and - # let hcid drop uid to bluetooth with the right linux capabilities - group bluetooth net_bt_admin misc - disabled - -service hfag /system/bin/sdptool add --channel=10 HFAG - user bluetooth - group bluetooth net_bt_admin - disabled - oneshot - -service hsag /system/bin/sdptool add --channel=11 HSAG - user bluetooth - group bluetooth net_bt_admin - disabled - oneshot - -service installd /system/bin/installd - socket installd stream 600 system system - -service flash_recovery /system/bin/flash_image recovery /system/recovery.img - oneshot diff --git a/sh/Android.mk b/sh/Android.mk deleted file mode 100644 index 09bb6ac174feaa5c860547b8c5de726cd6a9bc3c..0000000000000000000000000000000000000000 --- a/sh/Android.mk +++ /dev/null @@ -1,49 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - alias.c \ - arith.c \ - arith_lex.c \ - builtins.c \ - cd.c \ - error.c \ - eval.c \ - exec.c \ - expand.c \ - input.c \ - jobs.c \ - main.c \ - memalloc.c \ - miscbltin.c \ - mystring.c \ - nodes.c \ - options.c \ - parser.c \ - redir.c \ - show.c \ - syntax.c \ - trap.c \ - output.c \ - var.c \ - bltin/echo.c \ - init.c - -LOCAL_MODULE:= sh - -LOCAL_CFLAGS += -DSHELL - -make_ash_files: PRIVATE_SRC_FILES := $(SRC_FILES) -make_ash_files: PRIVATE_CFLAGS := $(LOCAL_CFLAGS) -make_ash_files: - p4 edit arith.c arith_lex.c arith.h builtins.h builtins.c - p4 edit init.c nodes.c nodes.h token.h - sh ./mktokens - bison -o arith.c arith.y - flex -o arith_lex.c arith_lex.l - perl -ne 'print if ( /^\#\s*define\s+ARITH/ );' < arith.c > arith.h - sh ./mkbuiltins shell.h builtins.def . -Wall -O2 - sh ./mknodes.sh nodetypes nodes.c.pat . - sh ./mkinit.sh $(PRIVATE_SRC_FILES) - -include $(BUILD_EXECUTABLE) diff --git a/sh/MODULE_LICENSE_BSD b/sh/MODULE_LICENSE_BSD deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/sh/NOTICE b/sh/NOTICE deleted file mode 100644 index 49a66d2738ccfca81351e493f59af5f45a679ddf..0000000000000000000000000000000000000000 --- a/sh/NOTICE +++ /dev/null @@ -1,31 +0,0 @@ -Copyright (c) 1991, 1993 - The Regents of the University of California. All rights reserved. - -This code is derived from software contributed to Berkeley by -Kenneth Almquist. - -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. -3. 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. - - diff --git a/sh/TOUR b/sh/TOUR deleted file mode 100644 index f5c00c4f346ebb3e4cfc9629df7b9d75030d9702..0000000000000000000000000000000000000000 --- a/sh/TOUR +++ /dev/null @@ -1,357 +0,0 @@ -# $NetBSD: TOUR,v 1.8 1996/10/16 14:24:56 christos Exp $ -# @(#)TOUR 8.1 (Berkeley) 5/31/93 - -NOTE -- This is the original TOUR paper distributed with ash and -does not represent the current state of the shell. It is provided anyway -since it provides helpful information for how the shell is structured, -but be warned that things have changed -- the current shell is -still under development. - -================================================================ - - A Tour through Ash - - Copyright 1989 by Kenneth Almquist. - - -DIRECTORIES: The subdirectory bltin contains commands which can -be compiled stand-alone. The rest of the source is in the main -ash directory. - -SOURCE CODE GENERATORS: Files whose names begin with "mk" are -programs that generate source code. A complete list of these -programs is: - - program intput files generates - ------- ------------ --------- - mkbuiltins builtins builtins.h builtins.c - mkinit *.c init.c - mknodes nodetypes nodes.h nodes.c - mksignames - signames.h signames.c - mksyntax - syntax.h syntax.c - mktokens - token.h - bltin/mkexpr unary_op binary_op operators.h operators.c - -There are undoubtedly too many of these. Mkinit searches all the -C source files for entries looking like: - - INIT { - x = 1; /* executed during initialization */ - } - - RESET { - x = 2; /* executed when the shell does a longjmp - back to the main command loop */ - } - - SHELLPROC { - x = 3; /* executed when the shell runs a shell procedure */ - } - -It pulls this code out into routines which are when particular -events occur. The intent is to improve modularity by isolating -the information about which modules need to be explicitly -initialized/reset within the modules themselves. - -Mkinit recognizes several constructs for placing declarations in -the init.c file. - INCLUDE "file.h" -includes a file. The storage class MKINIT makes a declaration -available in the init.c file, for example: - MKINIT int funcnest; /* depth of function calls */ -MKINIT alone on a line introduces a structure or union declara- -tion: - MKINIT - struct redirtab { - short renamed[10]; - }; -Preprocessor #define statements are copied to init.c without any -special action to request this. - -INDENTATION: The ash source is indented in multiples of six -spaces. The only study that I have heard of on the subject con- -cluded that the optimal amount to indent is in the range of four -to six spaces. I use six spaces since it is not too big a jump -from the widely used eight spaces. If you really hate six space -indentation, use the adjind (source included) program to change -it to something else. - -EXCEPTIONS: Code for dealing with exceptions appears in -exceptions.c. The C language doesn't include exception handling, -so I implement it using setjmp and longjmp. The global variable -exception contains the type of exception. EXERROR is raised by -calling error. EXINT is an interrupt. EXSHELLPROC is an excep- -tion which is raised when a shell procedure is invoked. The pur- -pose of EXSHELLPROC is to perform the cleanup actions associated -with other exceptions. After these cleanup actions, the shell -can interpret a shell procedure itself without exec'ing a new -copy of the shell. - -INTERRUPTS: In an interactive shell, an interrupt will cause an -EXINT exception to return to the main command loop. (Exception: -EXINT is not raised if the user traps interrupts using the trap -command.) The INTOFF and INTON macros (defined in exception.h) -provide uninterruptable critical sections. Between the execution -of INTOFF and the execution of INTON, interrupt signals will be -held for later delivery. INTOFF and INTON can be nested. - -MEMALLOC.C: Memalloc.c defines versions of malloc and realloc -which call error when there is no memory left. It also defines a -stack oriented memory allocation scheme. Allocating off a stack -is probably more efficient than allocation using malloc, but the -big advantage is that when an exception occurs all we have to do -to free up the memory in use at the time of the exception is to -restore the stack pointer. The stack is implemented using a -linked list of blocks. - -STPUTC: If the stack were contiguous, it would be easy to store -strings on the stack without knowing in advance how long the -string was going to be: - p = stackptr; - *p++ = c; /* repeated as many times as needed */ - stackptr = p; -The folloing three macros (defined in memalloc.h) perform these -operations, but grow the stack if you run off the end: - STARTSTACKSTR(p); - STPUTC(c, p); /* repeated as many times as needed */ - grabstackstr(p); - -We now start a top-down look at the code: - -MAIN.C: The main routine performs some initialization, executes -the user's profile if necessary, and calls cmdloop. Cmdloop is -repeatedly parses and executes commands. - -OPTIONS.C: This file contains the option processing code. It is -called from main to parse the shell arguments when the shell is -invoked, and it also contains the set builtin. The -i and -j op- -tions (the latter turns on job control) require changes in signal -handling. The routines setjobctl (in jobs.c) and setinteractive -(in trap.c) are called to handle changes to these options. - -PARSING: The parser code is all in parser.c. A recursive des- -cent parser is used. Syntax tables (generated by mksyntax) are -used to classify characters during lexical analysis. There are -three tables: one for normal use, one for use when inside single -quotes, and one for use when inside double quotes. The tables -are machine dependent because they are indexed by character vari- -ables and the range of a char varies from machine to machine. - -PARSE OUTPUT: The output of the parser consists of a tree of -nodes. The various types of nodes are defined in the file node- -types. - -Nodes of type NARG are used to represent both words and the con- -tents of here documents. An early version of ash kept the con- -tents of here documents in temporary files, but keeping here do- -cuments in memory typically results in significantly better per- -formance. It would have been nice to make it an option to use -temporary files for here documents, for the benefit of small -machines, but the code to keep track of when to delete the tem- -porary files was complex and I never fixed all the bugs in it. -(AT&T has been maintaining the Bourne shell for more than ten -years, and to the best of my knowledge they still haven't gotten -it to handle temporary files correctly in obscure cases.) - -The text field of a NARG structure points to the text of the -word. The text consists of ordinary characters and a number of -special codes defined in parser.h. The special codes are: - - CTLVAR Variable substitution - CTLENDVAR End of variable substitution - CTLBACKQ Command substitution - CTLBACKQ|CTLQUOTE Command substitution inside double quotes - CTLESC Escape next character - -A variable substitution contains the following elements: - - CTLVAR type name '=' [ alternative-text CTLENDVAR ] - -The type field is a single character specifying the type of sub- -stitution. The possible types are: - - VSNORMAL $var - VSMINUS ${var-text} - VSMINUS|VSNUL ${var:-text} - VSPLUS ${var+text} - VSPLUS|VSNUL ${var:+text} - VSQUESTION ${var?text} - VSQUESTION|VSNUL ${var:?text} - VSASSIGN ${var=text} - VSASSIGN|VSNUL ${var=text} - -In addition, the type field will have the VSQUOTE flag set if the -variable is enclosed in double quotes. The name of the variable -comes next, terminated by an equals sign. If the type is not -VSNORMAL, then the text field in the substitution follows, ter- -minated by a CTLENDVAR byte. - -Commands in back quotes are parsed and stored in a linked list. -The locations of these commands in the string are indicated by -CTLBACKQ and CTLBACKQ+CTLQUOTE characters, depending upon whether -the back quotes were enclosed in double quotes. - -The character CTLESC escapes the next character, so that in case -any of the CTL characters mentioned above appear in the input, -they can be passed through transparently. CTLESC is also used to -escape '*', '?', '[', and '!' characters which were quoted by the -user and thus should not be used for file name generation. - -CTLESC characters have proved to be particularly tricky to get -right. In the case of here documents which are not subject to -variable and command substitution, the parser doesn't insert any -CTLESC characters to begin with (so the contents of the text -field can be written without any processing). Other here docu- -ments, and words which are not subject to splitting and file name -generation, have the CTLESC characters removed during the vari- -able and command substitution phase. Words which are subject -splitting and file name generation have the CTLESC characters re- -moved as part of the file name phase. - -EXECUTION: Command execution is handled by the following files: - eval.c The top level routines. - redir.c Code to handle redirection of input and output. - jobs.c Code to handle forking, waiting, and job control. - exec.c Code to to path searches and the actual exec sys call. - expand.c Code to evaluate arguments. - var.c Maintains the variable symbol table. Called from expand.c. - -EVAL.C: Evaltree recursively executes a parse tree. The exit -status is returned in the global variable exitstatus. The alter- -native entry evalbackcmd is called to evaluate commands in back -quotes. It saves the result in memory if the command is a buil- -tin; otherwise it forks off a child to execute the command and -connects the standard output of the child to a pipe. - -JOBS.C: To create a process, you call makejob to return a job -structure, and then call forkshell (passing the job structure as -an argument) to create the process. Waitforjob waits for a job -to complete. These routines take care of process groups if job -control is defined. - -REDIR.C: Ash allows file descriptors to be redirected and then -restored without forking off a child process. This is accom- -plished by duplicating the original file descriptors. The redir- -tab structure records where the file descriptors have be dupli- -cated to. - -EXEC.C: The routine find_command locates a command, and enters -the command in the hash table if it is not already there. The -third argument specifies whether it is to print an error message -if the command is not found. (When a pipeline is set up, -find_command is called for all the commands in the pipeline be- -fore any forking is done, so to get the commands into the hash -table of the parent process. But to make command hashing as -transparent as possible, we silently ignore errors at that point -and only print error messages if the command cannot be found -later.) - -The routine shellexec is the interface to the exec system call. - -EXPAND.C: Arguments are processed in three passes. The first -(performed by the routine argstr) performs variable and command -substitution. The second (ifsbreakup) performs word splitting -and the third (expandmeta) performs file name generation. If the -"/u" directory is simulated, then when "/u/username" is replaced -by the user's home directory, the flag "didudir" is set. This -tells the cd command that it should print out the directory name, -just as it would if the "/u" directory were implemented using -symbolic links. - -VAR.C: Variables are stored in a hash table. Probably we should -switch to extensible hashing. The variable name is stored in the -same string as the value (using the format "name=value") so that -no string copying is needed to create the environment of a com- -mand. Variables which the shell references internally are preal- -located so that the shell can reference the values of these vari- -ables without doing a lookup. - -When a program is run, the code in eval.c sticks any environment -variables which precede the command (as in "PATH=xxx command") in -the variable table as the simplest way to strip duplicates, and -then calls "environment" to get the value of the environment. -There are two consequences of this. First, if an assignment to -PATH precedes the command, the value of PATH before the assign- -ment must be remembered and passed to shellexec. Second, if the -program turns out to be a shell procedure, the strings from the -environment variables which preceded the command must be pulled -out of the table and replaced with strings obtained from malloc, -since the former will automatically be freed when the stack (see -the entry on memalloc.c) is emptied. - -BUILTIN COMMANDS: The procedures for handling these are scat- -tered throughout the code, depending on which location appears -most appropriate. They can be recognized because their names al- -ways end in "cmd". The mapping from names to procedures is -specified in the file builtins, which is processed by the mkbuil- -tins command. - -A builtin command is invoked with argc and argv set up like a -normal program. A builtin command is allowed to overwrite its -arguments. Builtin routines can call nextopt to do option pars- -ing. This is kind of like getopt, but you don't pass argc and -argv to it. Builtin routines can also call error. This routine -normally terminates the shell (or returns to the main command -loop if the shell is interactive), but when called from a builtin -command it causes the builtin command to terminate with an exit -status of 2. - -The directory bltins contains commands which can be compiled in- -dependently but can also be built into the shell for efficiency -reasons. The makefile in this directory compiles these programs -in the normal fashion (so that they can be run regardless of -whether the invoker is ash), but also creates a library named -bltinlib.a which can be linked with ash. The header file bltin.h -takes care of most of the differences between the ash and the -stand-alone environment. The user should call the main routine -"main", and #define main to be the name of the routine to use -when the program is linked into ash. This #define should appear -before bltin.h is included; bltin.h will #undef main if the pro- -gram is to be compiled stand-alone. - -CD.C: This file defines the cd and pwd builtins. The pwd com- -mand runs /bin/pwd the first time it is invoked (unless the user -has already done a cd to an absolute pathname), but then -remembers the current directory and updates it when the cd com- -mand is run, so subsequent pwd commands run very fast. The main -complication in the cd command is in the docd command, which -resolves symbolic links into actual names and informs the user -where the user ended up if he crossed a symbolic link. - -SIGNALS: Trap.c implements the trap command. The routine set- -signal figures out what action should be taken when a signal is -received and invokes the signal system call to set the signal ac- -tion appropriately. When a signal that a user has set a trap for -is caught, the routine "onsig" sets a flag. The routine dotrap -is called at appropriate points to actually handle the signal. -When an interrupt is caught and no trap has been set for that -signal, the routine "onint" in error.c is called. - -OUTPUT: Ash uses it's own output routines. There are three out- -put structures allocated. "Output" represents the standard out- -put, "errout" the standard error, and "memout" contains output -which is to be stored in memory. This last is used when a buil- -tin command appears in backquotes, to allow its output to be col- -lected without doing any I/O through the UNIX operating system. -The variables out1 and out2 normally point to output and errout, -respectively, but they are set to point to memout when appropri- -ate inside backquotes. - -INPUT: The basic input routine is pgetc, which reads from the -current input file. There is a stack of input files; the current -input file is the top file on this stack. The code allows the -input to come from a string rather than a file. (This is for the --c option and the "." and eval builtin commands.) The global -variable plinno is saved and restored when files are pushed and -popped from the stack. The parser routines store the number of -the current line in this variable. - -DEBUGGING: If DEBUG is defined in shell.h, then the shell will -write debugging information to the file $HOME/trace. Most of -this is done using the TRACE macro, which takes a set of printf -arguments inside two sets of parenthesis. Example: -"TRACE(("n=%d0, n))". The double parenthesis are necessary be- -cause the preprocessor can't handle functions with a variable -number of arguments. Defining DEBUG also causes the shell to -generate a core dump if it is sent a quit signal. The tracing -code is in show.c. diff --git a/sh/alias.c b/sh/alias.c deleted file mode 100644 index 59a3dc1543ca08bd80eab5c309d442885b0c06d8..0000000000000000000000000000000000000000 --- a/sh/alias.c +++ /dev/null @@ -1,273 +0,0 @@ -/* $NetBSD: alias.c,v 1.12 2003/08/07 09:05:29 agc Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: alias.c,v 1.12 2003/08/07 09:05:29 agc Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> -#include "shell.h" -#include "input.h" -#include "output.h" -#include "error.h" -#include "memalloc.h" -#include "mystring.h" -#include "alias.h" -#include "options.h" /* XXX for argptr (should remove?) */ -#include "var.h" - -#define ATABSIZE 39 - -struct alias *atab[ATABSIZE]; - -STATIC void setalias(char *, char *); -STATIC int unalias(char *); -STATIC struct alias **hashalias(char *); - -STATIC -void -setalias(char *name, char *val) -{ - struct alias *ap, **app; - - app = hashalias(name); - for (ap = *app; ap; ap = ap->next) { - if (equal(name, ap->name)) { - INTOFF; - ckfree(ap->val); - ap->val = savestr(val); - INTON; - return; - } - } - /* not found */ - INTOFF; - ap = ckmalloc(sizeof (struct alias)); - ap->name = savestr(name); - /* - * XXX - HACK: in order that the parser will not finish reading the - * alias value off the input before processing the next alias, we - * dummy up an extra space at the end of the alias. This is a crock - * and should be re-thought. The idea (if you feel inclined to help) - * is to avoid alias recursions. The mechanism used is: when - * expanding an alias, the value of the alias is pushed back on the - * input as a string and a pointer to the alias is stored with the - * string. The alias is marked as being in use. When the input - * routine finishes reading the string, it markes the alias not - * in use. The problem is synchronization with the parser. Since - * it reads ahead, the alias is marked not in use before the - * resulting token(s) is next checked for further alias sub. The - * H A C K is that we add a little fluff after the alias value - * so that the string will not be exhausted. This is a good - * idea ------- ***NOT*** - */ -#ifdef notyet - ap->val = savestr(val); -#else /* hack */ - { - int len = strlen(val); - ap->val = ckmalloc(len + 2); - memcpy(ap->val, val, len); - ap->val[len] = ' '; /* fluff */ - ap->val[len+1] = '\0'; - } -#endif - ap->next = *app; - *app = ap; - INTON; -} - -STATIC int -unalias(char *name) -{ - struct alias *ap, **app; - - app = hashalias(name); - - for (ap = *app; ap; app = &(ap->next), ap = ap->next) { - if (equal(name, ap->name)) { - /* - * if the alias is currently in use (i.e. its - * buffer is being used by the input routine) we - * just null out the name instead of freeing it. - * We could clear it out later, but this situation - * is so rare that it hardly seems worth it. - */ - if (ap->flag & ALIASINUSE) - *ap->name = '\0'; - else { - INTOFF; - *app = ap->next; - ckfree(ap->name); - ckfree(ap->val); - ckfree(ap); - INTON; - } - return (0); - } - } - - return (1); -} - -#ifdef mkinit -MKINIT void rmaliases(void); - -SHELLPROC { - rmaliases(); -} -#endif - -void -rmaliases(void) -{ - struct alias *ap, *tmp; - int i; - - INTOFF; - for (i = 0; i < ATABSIZE; i++) { - ap = atab[i]; - atab[i] = NULL; - while (ap) { - ckfree(ap->name); - ckfree(ap->val); - tmp = ap; - ap = ap->next; - ckfree(tmp); - } - } - INTON; -} - -struct alias * -lookupalias(char *name, int check) -{ - struct alias *ap = *hashalias(name); - - for (; ap; ap = ap->next) { - if (equal(name, ap->name)) { - if (check && (ap->flag & ALIASINUSE)) - return (NULL); - return (ap); - } - } - - return (NULL); -} - -char * -get_alias_text(char *name) -{ - struct alias *ap; - - ap = lookupalias(name, 0); - if (ap == NULL) - return NULL; - return ap->val; -} - -/* - * TODO - sort output - */ -int -aliascmd(int argc, char **argv) -{ - char *n, *v; - int ret = 0; - struct alias *ap; - - if (argc == 1) { - int i; - - for (i = 0; i < ATABSIZE; i++) - for (ap = atab[i]; ap; ap = ap->next) { - if (*ap->name != '\0') { - out1fmt("alias %s=", ap->name); - print_quoted(ap->val); - out1c('\n'); - } - } - return (0); - } - while ((n = *++argv) != NULL) { - if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ - if ((ap = lookupalias(n, 0)) == NULL) { - outfmt(out2, "alias: %s not found\n", n); - ret = 1; - } else { - out1fmt("alias %s=", n); - print_quoted(ap->val); - out1c('\n'); - } - } else { - *v++ = '\0'; - setalias(n, v); - } - } - - return (ret); -} - -int -unaliascmd(int argc, char **argv) -{ - int i; - - while ((i = nextopt("a")) != '\0') { - if (i == 'a') { - rmaliases(); - return (0); - } - } - for (i = 0; *argptr; argptr++) - i = unalias(*argptr); - - return (i); -} - -STATIC struct alias ** -hashalias(char *p) -{ - unsigned int hashval; - - hashval = *p << 4; - while (*p) - hashval+= *p++; - return &atab[hashval % ATABSIZE]; -} diff --git a/sh/alias.h b/sh/alias.h deleted file mode 100644 index 7ce25f482d3929ef5f09e5f24ef712b2e3c7e62f..0000000000000000000000000000000000000000 --- a/sh/alias.h +++ /dev/null @@ -1,50 +0,0 @@ -/* $NetBSD: alias.h,v 1.6 2003/08/07 09:05:29 agc Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)alias.h 8.2 (Berkeley) 5/4/95 - */ - -#define ALIASINUSE 1 - -struct alias { - struct alias *next; - char *name; - char *val; - int flag; -}; - -struct alias *lookupalias(char *, int); -char *get_alias_text(char *); -int aliascmd(int, char **); -int unaliascmd(int, char **); -void rmaliases(void); diff --git a/sh/arith.c b/sh/arith.c deleted file mode 100644 index f8f92a9ebb723660fce1d20f92ae3276a4b84808..0000000000000000000000000000000000000000 --- a/sh/arith.c +++ /dev/null @@ -1,1587 +0,0 @@ -/* A Bison parser, made by GNU Bison 1.875d. */ - -/* Skeleton parser for Yacc-like parsing with Bison, - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -/* As a special exception, when this file is copied by Bison into a - Bison output file, you may use that output file without restriction. - This special exception was added by the Free Software Foundation - in version 1.24 of Bison. */ - -/* Written by Richard Stallman by simplifying the original so called - ``semantic'' parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - ARITH_NUM = 258, - ARITH_LPAREN = 259, - ARITH_RPAREN = 260, - ARITH_OR = 261, - ARITH_AND = 262, - ARITH_BOR = 263, - ARITH_BXOR = 264, - ARITH_BAND = 265, - ARITH_NE = 266, - ARITH_EQ = 267, - ARITH_LE = 268, - ARITH_GE = 269, - ARITH_GT = 270, - ARITH_LT = 271, - ARITH_RSHIFT = 272, - ARITH_LSHIFT = 273, - ARITH_SUB = 274, - ARITH_ADD = 275, - ARITH_REM = 276, - ARITH_DIV = 277, - ARITH_MUL = 278, - ARITH_BNOT = 279, - ARITH_NOT = 280, - ARITH_UNARYPLUS = 281, - ARITH_UNARYMINUS = 282 - }; -#endif -#define ARITH_NUM 258 -#define ARITH_LPAREN 259 -#define ARITH_RPAREN 260 -#define ARITH_OR 261 -#define ARITH_AND 262 -#define ARITH_BOR 263 -#define ARITH_BXOR 264 -#define ARITH_BAND 265 -#define ARITH_NE 266 -#define ARITH_EQ 267 -#define ARITH_LE 268 -#define ARITH_GE 269 -#define ARITH_GT 270 -#define ARITH_LT 271 -#define ARITH_RSHIFT 272 -#define ARITH_LSHIFT 273 -#define ARITH_SUB 274 -#define ARITH_ADD 275 -#define ARITH_REM 276 -#define ARITH_DIV 277 -#define ARITH_MUL 278 -#define ARITH_BNOT 279 -#define ARITH_NOT 280 -#define ARITH_UNARYPLUS 281 -#define ARITH_UNARYMINUS 282 - - - - -/* Copy the first part of user declarations. */ -#line 1 "arith.y" - -/* $NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> -#include "expand.h" -#include "shell.h" -#include "error.h" -#include "output.h" -#include "memalloc.h" - -const char *arith_buf, *arith_startbuf; - -void yyerror(const char *); -#ifdef TESTARITH -int main(int , char *[]); -int error(char *); -#endif - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED) -typedef int YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ - - -/* Line 214 of yacc.c. */ -#line 202 "arith.c" - -#if ! defined (yyoverflow) || YYERROR_VERBOSE - -# ifndef YYFREE -# define YYFREE free -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# endif - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# define YYSTACK_ALLOC alloca -# endif -# else -# if defined (alloca) || defined (_ALLOCA_H) -# define YYSTACK_ALLOC alloca -# else -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) -# else -# if defined (__STDC__) || defined (__cplusplus) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# endif -#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */ - - -#if (! defined (yyoverflow) \ - && (! defined (__cplusplus) \ - || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - short int yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (short int) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined (__GNUC__) && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - register YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (0) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (0) - -#endif - -#if defined (__STDC__) || defined (__cplusplus) - typedef signed char yysigned_char; -#else - typedef short int yysigned_char; -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 14 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 170 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 28 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 26 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 52 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 282 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const unsigned char yytranslate[] = -{ - 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const unsigned char yyprhs[] = -{ - 0, 0, 3, 5, 9, 13, 17, 21, 25, 29, - 33, 37, 41, 45, 49, 53, 57, 61, 65, 69, - 73, 77, 81, 84, 87, 90, 93 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yysigned_char yyrhs[] = -{ - 29, 0, -1, 30, -1, 4, 30, 5, -1, 30, - 6, 30, -1, 30, 7, 30, -1, 30, 8, 30, - -1, 30, 9, 30, -1, 30, 10, 30, -1, 30, - 12, 30, -1, 30, 15, 30, -1, 30, 14, 30, - -1, 30, 16, 30, -1, 30, 13, 30, -1, 30, - 11, 30, -1, 30, 18, 30, -1, 30, 17, 30, - -1, 30, 20, 30, -1, 30, 19, 30, -1, 30, - 23, 30, -1, 30, 22, 30, -1, 30, 21, 30, - -1, 25, 30, -1, 24, 30, -1, 19, 30, -1, - 20, 30, -1, 3, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const unsigned char yyrline[] = -{ - 0, 76, 76, 82, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, - 99, 104, 109, 110, 111, 112, 113 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE -/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "ARITH_NUM", "ARITH_LPAREN", - "ARITH_RPAREN", "ARITH_OR", "ARITH_AND", "ARITH_BOR", "ARITH_BXOR", - "ARITH_BAND", "ARITH_NE", "ARITH_EQ", "ARITH_LE", "ARITH_GE", "ARITH_GT", - "ARITH_LT", "ARITH_RSHIFT", "ARITH_LSHIFT", "ARITH_SUB", "ARITH_ADD", - "ARITH_REM", "ARITH_DIV", "ARITH_MUL", "ARITH_BNOT", "ARITH_NOT", - "ARITH_UNARYPLUS", "ARITH_UNARYMINUS", "$accept", "exp", "expr", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const unsigned short int yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const unsigned char yyr1[] = -{ - 0, 28, 29, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const unsigned char yyr2[] = -{ - 0, 2, 1, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 2, 2, 2, 1 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const unsigned char yydefact[] = -{ - 0, 26, 0, 0, 0, 0, 0, 0, 2, 0, - 24, 25, 23, 22, 1, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 4, 5, 6, 7, 8, 14, - 9, 13, 11, 10, 12, 16, 15, 18, 17, 21, - 20, 19 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yysigned_char yydefgoto[] = -{ - -1, 7, 8 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -13 -static const short int yypact[] = -{ - 28, -13, 28, 28, 28, 28, 28, 12, 67, 49, - -13, -13, -13, -13, -13, 28, 28, 28, 28, 28, - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, - 28, 28, 28, -13, 84, 100, 115, 23, 128, 139, - 139, -12, -12, -12, -12, 144, 144, 147, 147, -13, - -13, -13 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yysigned_char yypgoto[] = -{ - -13, -13, -2 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -1 -static const unsigned char yytable[] = -{ - 9, 10, 11, 12, 13, 26, 27, 28, 29, 30, - 31, 32, 14, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, - 51, 1, 2, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, 3, 4, 0, - 0, 0, 5, 6, 33, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 25, 26, 27, 28, 29, 30, 31, 32, 17, 18, - 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, - 29, 30, 31, 32, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 20, - 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, - 31, 32, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, 28, 29, 30, 31, 32, 30, 31, - 32 -}; - -static const yysigned_char yycheck[] = -{ - 2, 3, 4, 5, 6, 17, 18, 19, 20, 21, - 22, 23, 0, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 3, 4, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 19, 20, -1, - -1, -1, 24, 25, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 23, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 19, 20, 21, 22, 23, 21, 22, - 23 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const unsigned char yystos[] = -{ - 0, 3, 4, 19, 20, 24, 25, 29, 30, 30, - 30, 30, 30, 30, 0, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 5, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30 -}; - -#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__) -# define YYSIZE_T __SIZE_TYPE__ -#endif -#if ! defined (YYSIZE_T) && defined (size_t) -# define YYSIZE_T size_t -#endif -#if ! defined (YYSIZE_T) -# if defined (__STDC__) || defined (__cplusplus) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# endif -#endif -#if ! defined (YYSIZE_T) -# define YYSIZE_T unsigned int -#endif - -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. */ - -#define YYFAIL goto yyerrlab - -#define YYRECOVERING() (!!yyerrstatus) - -#define YYBACKUP(Token, Value) \ -do \ - if (yychar == YYEMPTY && yylen == 1) \ - { \ - yychar = (Token); \ - yylval = (Value); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK; \ - goto yybackup; \ - } \ - else \ - { \ - yyerror ("syntax error: cannot back up");\ - YYERROR; \ - } \ -while (0) - -#define YYTERROR 1 -#define YYERRCODE 256 - -/* YYLLOC_DEFAULT -- Compute the default location (before the actions - are run). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - ((Current).first_line = (Rhs)[1].first_line, \ - (Current).first_column = (Rhs)[1].first_column, \ - (Current).last_line = (Rhs)[N].last_line, \ - (Current).last_column = (Rhs)[N].last_column) -#endif - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (0) - -# define YYDSYMPRINT(Args) \ -do { \ - if (yydebug) \ - yysymprint Args; \ -} while (0) - -# define YYDSYMPRINTF(Title, Token, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yysymprint (stderr, \ - Token, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (0) - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_stack_print (short int *bottom, short int *top) -#else -static void -yy_stack_print (bottom, top) - short int *bottom; - short int *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (/* Nothing. */; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (0) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yy_reduce_print (int yyrule) -#else -static void -yy_reduce_print (yyrule) - int yyrule; -#endif -{ - int yyi; - unsigned int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ", - yyrule - 1, yylno); - /* Print the symbols being reduced, and their result. */ - for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++) - YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]); - YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]); -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (Rule); \ -} while (0) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YYDSYMPRINT(Args) -# define YYDSYMPRINTF(Title, Token, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0 -# undef YYMAXDEPTH -#endif - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined (__GLIBC__) && defined (_STRING_H) -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -static YYSIZE_T -# if defined (__STDC__) || defined (__cplusplus) -yystrlen (const char *yystr) -# else -yystrlen (yystr) - const char *yystr; -# endif -{ - register const char *yys = yystr; - - while (*yys++ != '\0') - continue; - - return yys - yystr - 1; -} -# endif -# endif - -# ifndef yystpcpy -# if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE) -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -static char * -# if defined (__STDC__) || defined (__cplusplus) -yystpcpy (char *yydest, const char *yysrc) -# else -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -# endif -{ - register char *yyd = yydest; - register const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -#endif /* !YYERROR_VERBOSE */ - - - -#if YYDEBUG -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep) -#else -static void -yysymprint (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - if (yytype < YYNTOKENS) - { - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); -# ifdef YYPRINT - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# endif - } - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - switch (yytype) - { - default: - break; - } - YYFPRINTF (yyoutput, ")"); -} - -#endif /* ! YYDEBUG */ -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -#if defined (__STDC__) || defined (__cplusplus) -static void -yydestruct (int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yytype, yyvaluep) - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - /* Pacify ``unused variable'' warnings. */ - (void) yyvaluep; - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM); -# else -int yyparse (); -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The lookahead symbol. */ -int yychar; - -/* The semantic value of the lookahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -# if defined (__STDC__) || defined (__cplusplus) -int yyparse (void *YYPARSE_PARAM) -# else -int yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -# endif -#else /* ! YYPARSE_PARAM */ -#if defined (__STDC__) || defined (__cplusplus) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - register int yystate; - register int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Lookahead token as an internal (translated) token number. */ - int yytoken = 0; - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - short int yyssa[YYINITDEPTH]; - short int *yyss = yyssa; - register short int *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - register YYSTYPE *yyvsp; - - - -#define YYPOPSTACK (yyvsp--, yyssp--) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* When reducing, the number of symbols on the RHS of the reduced - rule. */ - int yylen; - - YYDPRINTF ((stderr, "Starting parse\n")); - - yystate = 0; - yyerrstatus = 0; - yynerrs = 0; - yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - - yyssp = yyss; - yyvsp = yyvs; - - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. so pushing a state here evens the stacks. - */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - short int *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow ("parser stack overflow", - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyoverflowlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyoverflowlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - short int *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyoverflowlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - -/* Do appropriate processing given the current state. */ -/* Read a lookahead token if we need one and don't already have one. */ -/* yyresume: */ - - /* First try to decide what to do without reference to lookahead token. */ - - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a lookahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Shift the lookahead token. */ - YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken])); - - /* Discard the token being shifted unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - *++yyvsp = yylval; - - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - yystate = yyn; - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 2: -#line 76 "arith.y" - { - return (yyvsp[0]); - ;} - break; - - case 3: -#line 82 "arith.y" - { yyval = yyvsp[-1]; ;} - break; - - case 4: -#line 83 "arith.y" - { yyval = yyvsp[-2] ? yyvsp[-2] : yyvsp[0] ? yyvsp[0] : 0; ;} - break; - - case 5: -#line 84 "arith.y" - { yyval = yyvsp[-2] ? ( yyvsp[0] ? yyvsp[0] : 0 ) : 0; ;} - break; - - case 6: -#line 85 "arith.y" - { yyval = yyvsp[-2] | yyvsp[0]; ;} - break; - - case 7: -#line 86 "arith.y" - { yyval = yyvsp[-2] ^ yyvsp[0]; ;} - break; - - case 8: -#line 87 "arith.y" - { yyval = yyvsp[-2] & yyvsp[0]; ;} - break; - - case 9: -#line 88 "arith.y" - { yyval = yyvsp[-2] == yyvsp[0]; ;} - break; - - case 10: -#line 89 "arith.y" - { yyval = yyvsp[-2] > yyvsp[0]; ;} - break; - - case 11: -#line 90 "arith.y" - { yyval = yyvsp[-2] >= yyvsp[0]; ;} - break; - - case 12: -#line 91 "arith.y" - { yyval = yyvsp[-2] < yyvsp[0]; ;} - break; - - case 13: -#line 92 "arith.y" - { yyval = yyvsp[-2] <= yyvsp[0]; ;} - break; - - case 14: -#line 93 "arith.y" - { yyval = yyvsp[-2] != yyvsp[0]; ;} - break; - - case 15: -#line 94 "arith.y" - { yyval = yyvsp[-2] << yyvsp[0]; ;} - break; - - case 16: -#line 95 "arith.y" - { yyval = yyvsp[-2] >> yyvsp[0]; ;} - break; - - case 17: -#line 96 "arith.y" - { yyval = yyvsp[-2] + yyvsp[0]; ;} - break; - - case 18: -#line 97 "arith.y" - { yyval = yyvsp[-2] - yyvsp[0]; ;} - break; - - case 19: -#line 98 "arith.y" - { yyval = yyvsp[-2] * yyvsp[0]; ;} - break; - - case 20: -#line 99 "arith.y" - { - if (yyvsp[0] == 0) - yyerror("division by zero"); - yyval = yyvsp[-2] / yyvsp[0]; - ;} - break; - - case 21: -#line 104 "arith.y" - { - if (yyvsp[0] == 0) - yyerror("division by zero"); - yyval = yyvsp[-2] % yyvsp[0]; - ;} - break; - - case 22: -#line 109 "arith.y" - { yyval = !(yyvsp[0]); ;} - break; - - case 23: -#line 110 "arith.y" - { yyval = ~(yyvsp[0]); ;} - break; - - case 24: -#line 111 "arith.y" - { yyval = -(yyvsp[0]); ;} - break; - - case 25: -#line 112 "arith.y" - { yyval = yyvsp[0]; ;} - break; - - - } - -/* Line 1010 of yacc.c. */ -#line 1276 "arith.c" - - yyvsp -= yylen; - yyssp -= yylen; - - - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* Now `shift' the result of the reduction. Determine what state - that goes to, based on the state we popped back to and the rule - number reduced by. */ - - yyn = yyr1[yyn]; - - yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if YYERROR_VERBOSE - yyn = yypact[yystate]; - - if (YYPACT_NINF < yyn && yyn < YYLAST) - { - YYSIZE_T yysize = 0; - int yytype = YYTRANSLATE (yychar); - const char* yyprefix; - char *yymsg; - int yyx; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 0; - - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]); - yycount += 1; - if (yycount == 5) - { - yysize = 0; - break; - } - } - yysize += (sizeof ("syntax error, unexpected ") - + yystrlen (yytname[yytype])); - yymsg = (char *) YYSTACK_ALLOC (yysize); - if (yymsg != 0) - { - char *yyp = yystpcpy (yymsg, "syntax error, unexpected "); - yyp = yystpcpy (yyp, yytname[yytype]); - - if (yycount < 5) - { - yyprefix = ", expecting "; - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - yyp = yystpcpy (yyp, yyprefix); - yyp = yystpcpy (yyp, yytname[yyx]); - yyprefix = " or "; - } - } - yyerror (yymsg); - YYSTACK_FREE (yymsg); - } - else - yyerror ("syntax error; also virtual memory exhausted"); - } - else -#endif /* YYERROR_VERBOSE */ - yyerror ("syntax error"); - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse lookahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* If at end of input, pop the error token, - then the rest of the stack, then return failure. */ - if (yychar == YYEOF) - for (;;) - { - YYPOPSTACK; - if (yyssp == yyss) - YYABORT; - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[*yyssp], yyvsp); - } - } - else - { - YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc); - yydestruct (yytoken, &yylval); - yychar = YYEMPTY; - - } - } - - /* Else will try to reuse lookahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - -#ifdef __GNUC__ - /* Pacify GCC when the user code never invokes YYERROR and the label - yyerrorlab therefore never appears in user code. */ - if (0) - goto yyerrorlab; -#endif - - yyvsp -= yylen; - yyssp -= yylen; - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp); - yydestruct (yystos[yystate], yyvsp); - YYPOPSTACK; - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - YYDPRINTF ((stderr, "Shifting error token, ")); - - *++yyvsp = yylval; - - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*----------------------------------------------. -| yyoverflowlab -- parser overflow comes here. | -`----------------------------------------------*/ -yyoverflowlab: - yyerror ("parser stack overflow"); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif - return yyresult; -} - - -#line 115 "arith.y" - -int -arith(s) - const char *s; -{ - long result; - - arith_buf = arith_startbuf = s; - - INTOFF; - result = yyparse(); - arith_lex_reset(); /* reprime lex */ - INTON; - - return (result); -} - - -/* - * The exp(1) builtin. - */ -int -expcmd(argc, argv) - int argc; - char **argv; -{ - const char *p; - char *concat; - char **ap; - long i; - - if (argc > 1) { - p = argv[1]; - if (argc > 2) { - /* - * concatenate arguments - */ - STARTSTACKSTR(concat); - ap = argv + 2; - for (;;) { - while (*p) - STPUTC(*p++, concat); - if ((p = *ap++) == NULL) - break; - STPUTC(' ', concat); - } - STPUTC('\0', concat); - p = grabstackstr(concat); - } - } else - p = ""; - - i = arith(p); - - out1fmt("%ld\n", i); - return (! i); -} - -/*************************/ -#ifdef TEST_ARITH -#include <stdio.h> -main(argc, argv) - char *argv[]; -{ - printf("%d\n", exp(argv[1])); -} -error(s) - char *s; -{ - fprintf(stderr, "exp: %s\n", s); - exit(1); -} -#endif - -void -yyerror(s) - const char *s; -{ - -// yyerrok; - yyclearin; - arith_lex_reset(); /* reprime lex */ - error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); - /* NOTREACHED */ -} - - diff --git a/sh/arith.h b/sh/arith.h deleted file mode 100644 index f70c0933693480d8bad8eea642f4132823895a0c..0000000000000000000000000000000000000000 --- a/sh/arith.h +++ /dev/null @@ -1,25 +0,0 @@ -#define ARITH_NUM 258 -#define ARITH_LPAREN 259 -#define ARITH_RPAREN 260 -#define ARITH_OR 261 -#define ARITH_AND 262 -#define ARITH_BOR 263 -#define ARITH_BXOR 264 -#define ARITH_BAND 265 -#define ARITH_NE 266 -#define ARITH_EQ 267 -#define ARITH_LE 268 -#define ARITH_GE 269 -#define ARITH_GT 270 -#define ARITH_LT 271 -#define ARITH_RSHIFT 272 -#define ARITH_LSHIFT 273 -#define ARITH_SUB 274 -#define ARITH_ADD 275 -#define ARITH_REM 276 -#define ARITH_DIV 277 -#define ARITH_MUL 278 -#define ARITH_BNOT 279 -#define ARITH_NOT 280 -#define ARITH_UNARYPLUS 281 -#define ARITH_UNARYMINUS 282 diff --git a/sh/arith.y b/sh/arith.y deleted file mode 100644 index d51ed38f624729ccf3da049395071d1e492bc944..0000000000000000000000000000000000000000 --- a/sh/arith.y +++ /dev/null @@ -1,199 +0,0 @@ -%{ -/* $NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: arith.y,v 1.17 2003/09/17 17:33:36 jmmv Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> -#include "expand.h" -#include "shell.h" -#include "error.h" -#include "output.h" -#include "memalloc.h" - -const char *arith_buf, *arith_startbuf; - -void yyerror(const char *); -#ifdef TESTARITH -int main(int , char *[]); -int error(char *); -#endif - -%} -%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN - -%left ARITH_OR -%left ARITH_AND -%left ARITH_BOR -%left ARITH_BXOR -%left ARITH_BAND -%left ARITH_EQ ARITH_NE -%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE -%left ARITH_LSHIFT ARITH_RSHIFT -%left ARITH_ADD ARITH_SUB -%left ARITH_MUL ARITH_DIV ARITH_REM -%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT -%% - -exp: expr { - return ($1); - } - ; - - -expr: ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; } - | expr ARITH_OR expr { $$ = $1 ? $1 : $3 ? $3 : 0; } - | expr ARITH_AND expr { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } - | expr ARITH_BOR expr { $$ = $1 | $3; } - | expr ARITH_BXOR expr { $$ = $1 ^ $3; } - | expr ARITH_BAND expr { $$ = $1 & $3; } - | expr ARITH_EQ expr { $$ = $1 == $3; } - | expr ARITH_GT expr { $$ = $1 > $3; } - | expr ARITH_GE expr { $$ = $1 >= $3; } - | expr ARITH_LT expr { $$ = $1 < $3; } - | expr ARITH_LE expr { $$ = $1 <= $3; } - | expr ARITH_NE expr { $$ = $1 != $3; } - | expr ARITH_LSHIFT expr { $$ = $1 << $3; } - | expr ARITH_RSHIFT expr { $$ = $1 >> $3; } - | expr ARITH_ADD expr { $$ = $1 + $3; } - | expr ARITH_SUB expr { $$ = $1 - $3; } - | expr ARITH_MUL expr { $$ = $1 * $3; } - | expr ARITH_DIV expr { - if ($3 == 0) - yyerror("division by zero"); - $$ = $1 / $3; - } - | expr ARITH_REM expr { - if ($3 == 0) - yyerror("division by zero"); - $$ = $1 % $3; - } - | ARITH_NOT expr { $$ = !($2); } - | ARITH_BNOT expr { $$ = ~($2); } - | ARITH_SUB expr %prec ARITH_UNARYMINUS { $$ = -($2); } - | ARITH_ADD expr %prec ARITH_UNARYPLUS { $$ = $2; } - | ARITH_NUM - ; -%% -int -arith(s) - const char *s; -{ - long result; - - arith_buf = arith_startbuf = s; - - INTOFF; - result = yyparse(); - arith_lex_reset(); /* reprime lex */ - INTON; - - return (result); -} - - -/* - * The exp(1) builtin. - */ -int -expcmd(argc, argv) - int argc; - char **argv; -{ - const char *p; - char *concat; - char **ap; - long i; - - if (argc > 1) { - p = argv[1]; - if (argc > 2) { - /* - * concatenate arguments - */ - STARTSTACKSTR(concat); - ap = argv + 2; - for (;;) { - while (*p) - STPUTC(*p++, concat); - if ((p = *ap++) == NULL) - break; - STPUTC(' ', concat); - } - STPUTC('\0', concat); - p = grabstackstr(concat); - } - } else - p = ""; - - i = arith(p); - - out1fmt("%ld\n", i); - return (! i); -} - -/*************************/ -#ifdef TEST_ARITH -#include <stdio.h> -main(argc, argv) - char *argv[]; -{ - printf("%d\n", exp(argv[1])); -} -error(s) - char *s; -{ - fprintf(stderr, "exp: %s\n", s); - exit(1); -} -#endif - -void -yyerror(s) - const char *s; -{ - -// yyerrok; - yyclearin; - arith_lex_reset(); /* reprime lex */ - error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); - /* NOTREACHED */ -} diff --git a/sh/arith_lex.c b/sh/arith_lex.c deleted file mode 100644 index 9a132dd3433a6a9e4f6cfa575a55e1f5e98f3848..0000000000000000000000000000000000000000 --- a/sh/arith_lex.c +++ /dev/null @@ -1,1890 +0,0 @@ -#line 2 "arith_lex.c" - -#line 4 "arith_lex.c" - -#define YY_INT_ALIGNED short int - -/* A lexical scanner generated by flex */ - -#define FLEX_SCANNER -#define YY_FLEX_MAJOR_VERSION 2 -#define YY_FLEX_MINOR_VERSION 5 -#define YY_FLEX_SUBMINOR_VERSION 31 -#if YY_FLEX_SUBMINOR_VERSION > 0 -#define FLEX_BETA -#endif - -/* First, we deal with platform-specific or compiler-specific issues. */ - -/* begin standard C headers. */ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <stdlib.h> - -/* end standard C headers. */ - -/* flex integer type definitions */ - -#ifndef FLEXINT_H -#define FLEXINT_H - -/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ - -#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L -#include <inttypes.h> -typedef int8_t flex_int8_t; -typedef uint8_t flex_uint8_t; -typedef int16_t flex_int16_t; -typedef uint16_t flex_uint16_t; -typedef int32_t flex_int32_t; -typedef uint32_t flex_uint32_t; -#else -typedef signed char flex_int8_t; -typedef short int flex_int16_t; -typedef int flex_int32_t; -typedef unsigned char flex_uint8_t; -typedef unsigned short int flex_uint16_t; -typedef unsigned int flex_uint32_t; -#endif /* ! C99 */ - -/* Limits of integral types. */ -#ifndef INT8_MIN -#define INT8_MIN (-128) -#endif -#ifndef INT16_MIN -#define INT16_MIN (-32767-1) -#endif -#ifndef INT32_MIN -#define INT32_MIN (-2147483647-1) -#endif -#ifndef INT8_MAX -#define INT8_MAX (127) -#endif -#ifndef INT16_MAX -#define INT16_MAX (32767) -#endif -#ifndef INT32_MAX -#define INT32_MAX (2147483647) -#endif -#ifndef UINT8_MAX -#define UINT8_MAX (255U) -#endif -#ifndef UINT16_MAX -#define UINT16_MAX (65535U) -#endif -#ifndef UINT32_MAX -#define UINT32_MAX (4294967295U) -#endif - -#endif /* ! FLEXINT_H */ - -#ifdef __cplusplus - -/* The "const" storage-class-modifier is valid. */ -#define YY_USE_CONST - -#else /* ! __cplusplus */ - -#if __STDC__ - -#define YY_USE_CONST - -#endif /* __STDC__ */ -#endif /* ! __cplusplus */ - -#ifdef YY_USE_CONST -#define yyconst const -#else -#define yyconst -#endif - -/* Returned upon end-of-file. */ -#define YY_NULL 0 - -/* Promotes a possibly negative, possibly signed char to an unsigned - * integer for use as an array index. If the signed char is negative, - * we want to instead treat it as an 8-bit unsigned char, hence the - * double cast. - */ -#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) - -/* Enter a start condition. This macro really ought to take a parameter, - * but we do it the disgusting crufty way forced on us by the ()-less - * definition of BEGIN. - */ -#define BEGIN (yy_start) = 1 + 2 * - -/* Translate the current start state into a value that can be later handed - * to BEGIN to return to the state. The YYSTATE alias is for lex - * compatibility. - */ -#define YY_START (((yy_start) - 1) / 2) -#define YYSTATE YY_START - -/* Action number for EOF rule of a given start state. */ -#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) - -/* Special action meaning "start processing a new file". */ -#define YY_NEW_FILE yyrestart(yyin ) - -#define YY_END_OF_BUFFER_CHAR 0 - -/* Size of default input buffer. */ -#ifndef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#endif - -#ifndef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -typedef struct yy_buffer_state *YY_BUFFER_STATE; -#endif - -extern int yyleng; - -extern FILE *yyin, *yyout; - -#define EOB_ACT_CONTINUE_SCAN 0 -#define EOB_ACT_END_OF_FILE 1 -#define EOB_ACT_LAST_MATCH 2 - - #define YY_LESS_LINENO(n) - -/* Return all but the first "n" matched characters back to the input stream. */ -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - *yy_cp = (yy_hold_char); \ - YY_RESTORE_YY_MORE_OFFSET \ - (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ - YY_DO_BEFORE_ACTION; /* set up yytext again */ \ - } \ - while ( 0 ) - -#define unput(c) yyunput( c, (yytext_ptr) ) - -/* The following is because we cannot portably get our hands on size_t - * (without autoconf's help, which isn't available because we want - * flex-generated scanners to compile on their own). - */ - -#ifndef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -typedef unsigned int yy_size_t; -#endif - -#ifndef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -struct yy_buffer_state - { - FILE *yy_input_file; - - char *yy_ch_buf; /* input buffer */ - char *yy_buf_pos; /* current position in input buffer */ - - /* Size of input buffer in bytes, not including room for EOB - * characters. - */ - yy_size_t yy_buf_size; - - /* Number of characters read into yy_ch_buf, not including EOB - * characters. - */ - int yy_n_chars; - - /* Whether we "own" the buffer - i.e., we know we created it, - * and can realloc() it to grow it, and should free() it to - * delete it. - */ - int yy_is_our_buffer; - - /* Whether this is an "interactive" input source; if so, and - * if we're using stdio for input, then we want to use getc() - * instead of fread(), to make sure we stop fetching input after - * each newline. - */ - int yy_is_interactive; - - /* Whether we're considered to be at the beginning of a line. - * If so, '^' rules will be active on the next match, otherwise - * not. - */ - int yy_at_bol; - - int yy_bs_lineno; /**< The line count. */ - int yy_bs_column; /**< The column count. */ - - /* Whether to try to fill the input buffer when we reach the - * end of it. - */ - int yy_fill_buffer; - - int yy_buffer_status; - -#define YY_BUFFER_NEW 0 -#define YY_BUFFER_NORMAL 1 - /* When an EOF's been seen but there's still some text to process - * then we mark the buffer as YY_EOF_PENDING, to indicate that we - * shouldn't try reading from the input source any more. We might - * still have a bunch of tokens to match, though, because of - * possible backing-up. - * - * When we actually see the EOF, we change the status to "new" - * (via yyrestart()), so that the user can continue scanning by - * just pointing yyin at a new input file. - */ -#define YY_BUFFER_EOF_PENDING 2 - - }; -#endif /* !YY_STRUCT_YY_BUFFER_STATE */ - -/* Stack of input buffers. */ -static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ -static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ -static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ - -/* We provide macros for accessing buffer states in case in the - * future we want to put the buffer states in a more general - * "scanner state". - * - * Returns the top of the stack, or NULL. - */ -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ - ? (yy_buffer_stack)[(yy_buffer_stack_top)] \ - : NULL) - -/* Same as previous macro, but useful when we know that the buffer stack is not - * NULL or when we need an lvalue. For internal use only. - */ -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] - -/* yy_hold_char holds the character lost when yytext is formed. */ -static char yy_hold_char; -static int yy_n_chars; /* number of characters read into yy_ch_buf */ -int yyleng; - -/* Points to current character in buffer. */ -static char *yy_c_buf_p = (char *) 0; -static int yy_init = 1; /* whether we need to initialize */ -static int yy_start = 0; /* start state number */ - -/* Flag which is used to allow yywrap()'s to do buffer switches - * instead of setting up a fresh yyin. A bit of a hack ... - */ -static int yy_did_buffer_switch_on_eof; - -void yyrestart (FILE *input_file ); -void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); -YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); -void yy_delete_buffer (YY_BUFFER_STATE b ); -void yy_flush_buffer (YY_BUFFER_STATE b ); -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); -void yypop_buffer_state (void ); - -static void yyensure_buffer_stack (void ); -static void yy_load_buffer_state (void ); -static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); - -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) - -YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); -YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); -YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); - -void *yyalloc (yy_size_t ); -void *yyrealloc (void *,yy_size_t ); -void yyfree (void * ); - -#define yy_new_buffer yy_create_buffer - -#define yy_set_interactive(is_interactive) \ - { \ - if ( ! YY_CURRENT_BUFFER ){ \ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ - } - -#define yy_set_bol(at_bol) \ - { \ - if ( ! YY_CURRENT_BUFFER ){\ - yyensure_buffer_stack (); \ - YY_CURRENT_BUFFER_LVALUE = \ - yy_create_buffer(yyin,YY_BUF_SIZE ); \ - } \ - YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ - } - -#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) - -/* Begin user sect3 */ - -#define yywrap(n) 1 -#define YY_SKIP_YYWRAP - -typedef unsigned char YY_CHAR; - -FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; - -typedef int yy_state_type; - -extern int yylineno; - -int yylineno = 1; - -extern char *yytext; -#define yytext_ptr yytext - -static yy_state_type yy_get_previous_state (void ); -static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); -static int yy_get_next_buffer (void ); -static void yy_fatal_error (yyconst char msg[] ); - -/* Done after the current pattern has been matched and before the - * corresponding action - sets up yytext. - */ -#define YY_DO_BEFORE_ACTION \ - (yytext_ptr) = yy_bp; \ - yyleng = (size_t) (yy_cp - yy_bp); \ - (yy_hold_char) = *yy_cp; \ - *yy_cp = '\0'; \ - (yy_c_buf_p) = yy_cp; - -#define YY_NUM_RULES 29 -#define YY_END_OF_BUFFER 30 -/* This struct is not used in this scanner, - but its presence is necessary. */ -struct yy_trans_info - { - flex_int32_t yy_verify; - flex_int32_t yy_nxt; - }; -static yyconst flex_int16_t yy_accept[39] = - { 0, - 0, 0, 30, 28, 1, 1, 27, 23, 12, 6, - 7, 21, 24, 25, 22, 3, 4, 17, 28, 15, - 5, 11, 10, 26, 14, 9, 3, 0, 4, 19, - 18, 13, 16, 20, 5, 8, 2, 0 - } ; - -static yyconst flex_int32_t yy_ec[256] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 1, 1, 1, 5, 6, 1, 7, - 8, 9, 10, 1, 11, 1, 12, 13, 14, 14, - 14, 14, 14, 14, 14, 15, 15, 1, 1, 16, - 17, 18, 1, 1, 19, 19, 19, 19, 19, 19, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 1, 1, 1, 21, 20, 1, 19, 19, 19, 19, - - 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 22, - 20, 20, 1, 23, 1, 24, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 - } ; - -static yyconst flex_int32_t yy_meta[25] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 2, 2, 2, 1, 1, 1, 2, 3, - 1, 3, 1, 1 - } ; - -static yyconst flex_int16_t yy_base[41] = - { 0, - 0, 0, 47, 48, 48, 48, 29, 48, 39, 48, - 48, 48, 48, 48, 48, 12, 14, 14, 27, 15, - 0, 48, 20, 48, 48, 48, 22, 0, 24, 48, - 48, 48, 48, 48, 0, 48, 0, 48, 38, 40 - } ; - -static yyconst flex_int16_t yy_def[41] = - { 0, - 38, 1, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 39, 38, 38, 38, 38, 38, 38, 40, 38, 38, - 38, 38, 38, 38, 39, 38, 40, 0, 38, 38 - } ; - -static yyconst flex_int16_t yy_nxt[73] = - { 0, - 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 17, 18, 19, 20, 21, 21, - 22, 21, 23, 24, 27, 27, 29, 29, 29, 30, - 31, 33, 34, 28, 27, 27, 29, 29, 29, 35, - 35, 37, 36, 32, 26, 25, 38, 3, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38 - } ; - -static yyconst flex_int16_t yy_chk[73] = - { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 16, 16, 17, 17, 17, 18, - 18, 20, 20, 16, 27, 27, 29, 29, 29, 39, - 39, 40, 23, 19, 9, 7, 3, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, - 38, 38 - } ; - -static yy_state_type yy_last_accepting_state; -static char *yy_last_accepting_cpos; - -extern int yy_flex_debug; -int yy_flex_debug = 0; - -/* The intent behind this definition is that it'll catch - * any uses of REJECT which flex missed. - */ -#define REJECT reject_used_but_not_detected -#define yymore() yymore_used_but_not_detected -#define YY_MORE_ADJ 0 -#define YY_RESTORE_YY_MORE_OFFSET -char *yytext; -#line 1 "arith_lex.l" -#line 2 "arith_lex.l" -/* $NetBSD: arith_lex.l,v 1.12.6.1 2005/04/07 11:38:58 tron Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: arith_lex.l,v 1.12.6.1 2005/04/07 11:38:58 tron Exp $"); -#endif -#endif /* not lint */ - -#include <unistd.h> -#include "arith.h" -#include "error.h" -#include "expand.h" -#include "var.h" - -extern int yylval; -extern char *arith_buf, *arith_startbuf; -#undef YY_INPUT -#define YY_INPUT(buf,result,max) \ - result = (*buf = *arith_buf++) ? 1 : YY_NULL; -#define YY_NO_UNPUT -#line 526 "arith_lex.c" - -#define INITIAL 0 - -#ifndef YY_NO_UNISTD_H -/* Special case for "unistd.h", since it is non-ANSI. We include it way - * down here because we want the user's section 1 to have been scanned first. - * The user has a chance to override it with an option. - */ -#include <unistd.h> -#endif - -#ifndef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#endif - -/* Macros after this point can all be overridden by user definitions in - * section 1. - */ - -#ifndef YY_SKIP_YYWRAP -#ifdef __cplusplus -extern "C" int yywrap (void ); -#else -extern int yywrap (void ); -#endif -#endif - - static void yyunput (int c,char *buf_ptr ); - -#ifndef yytext_ptr -static void yy_flex_strncpy (char *,yyconst char *,int ); -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * ); -#endif - -#ifndef YY_NO_INPUT - -#ifdef __cplusplus -static int yyinput (void ); -#else -static int input (void ); -#endif - -#endif - -/* Amount of stuff to slurp up with each read. */ -#ifndef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#endif - -/* Copy whatever the last rule matched to the standard output. */ -#ifndef ECHO -/* This used to be an fputs(), but since the string might contain NUL's, - * we now use fwrite(). - */ -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#endif - -/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, - * is returned in "result". - */ -#ifndef YY_INPUT -#define YY_INPUT(buf,result,max_size) \ - if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ - { \ - int c = '*'; \ - size_t n; \ - for ( n = 0; n < max_size && \ - (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ - buf[n] = (char) c; \ - if ( c == '\n' ) \ - buf[n++] = (char) c; \ - if ( c == EOF && ferror( yyin ) ) \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - result = n; \ - } \ - else \ - { \ - errno=0; \ - while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ - { \ - if( errno != EINTR) \ - { \ - YY_FATAL_ERROR( "input in flex scanner failed" ); \ - break; \ - } \ - errno=0; \ - clearerr(yyin); \ - } \ - }\ -\ - -#endif - -/* No semi-colon after return; correct usage is to write "yyterminate();" - - * we don't want an extra ';' after the "return" because that will cause - * some compilers to complain about unreachable statements. - */ -#ifndef yyterminate -#define yyterminate() return YY_NULL -#endif - -/* Number of entries by which start-condition stack grows. */ -#ifndef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#endif - -/* Report a fatal error. */ -#ifndef YY_FATAL_ERROR -#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) -#endif - -/* end tables serialization structures and prototypes */ - -/* Default declaration of generated scanner - a define so the user can - * easily add parameters. - */ -#ifndef YY_DECL -#define YY_DECL_IS_OURS 1 - -extern int yylex (void); - -#define YY_DECL int yylex (void) -#endif /* !YY_DECL */ - -/* Code executed at the beginning of each rule, after yytext and yyleng - * have been set up. - */ -#ifndef YY_USER_ACTION -#define YY_USER_ACTION -#endif - -/* Code executed at the end of each rule. */ -#ifndef YY_BREAK -#define YY_BREAK break; -#endif - -#define YY_RULE_SETUP \ - YY_USER_ACTION - -/** The main scanner function which does all the work. - */ -YY_DECL -{ - register yy_state_type yy_current_state; - register char *yy_cp, *yy_bp; - register int yy_act; - -#line 60 "arith_lex.l" - -#line 679 "arith_lex.c" - - if ( (yy_init) ) - { - (yy_init) = 0; - -#ifdef YY_USER_INIT - YY_USER_INIT; -#endif - - if ( ! (yy_start) ) - (yy_start) = 1; /* first start state */ - - if ( ! yyin ) - yyin = stdin; - - if ( ! yyout ) - yyout = stdout; - - if ( ! YY_CURRENT_BUFFER ) { - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_load_buffer_state( ); - } - - while ( 1 ) /* loops until end-of-file is reached */ - { - yy_cp = (yy_c_buf_p); - - /* Support of yytext. */ - *yy_cp = (yy_hold_char); - - /* yy_bp points to the position in yy_ch_buf of the start of - * the current run. - */ - yy_bp = yy_cp; - - yy_current_state = (yy_start); -yy_match: - do - { - register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 39 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - ++yy_cp; - } - while ( yy_base[yy_current_state] != 48 ); - -yy_find_action: - yy_act = yy_accept[yy_current_state]; - if ( yy_act == 0 ) - { /* have to back up */ - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - yy_act = yy_accept[yy_current_state]; - } - - YY_DO_BEFORE_ACTION; - -do_action: /* This label is used only to access EOF actions. */ - - switch ( yy_act ) - { /* beginning of action switch */ - case 0: /* must back up */ - /* undo the effects of YY_DO_BEFORE_ACTION */ - *yy_cp = (yy_hold_char); - yy_cp = (yy_last_accepting_cpos); - yy_current_state = (yy_last_accepting_state); - goto yy_find_action; - -case 1: -/* rule 1 can match eol */ -YY_RULE_SETUP -#line 61 "arith_lex.l" -{ ; } - YY_BREAK -case 2: -YY_RULE_SETUP -#line 62 "arith_lex.l" -{ yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } - YY_BREAK -case 3: -YY_RULE_SETUP -#line 63 "arith_lex.l" -{ yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } - YY_BREAK -case 4: -YY_RULE_SETUP -#line 64 "arith_lex.l" -{ yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } - YY_BREAK -case 5: -YY_RULE_SETUP -#line 65 "arith_lex.l" -{ char *v = lookupvar(yytext); - if (v) { - yylval = strtol(v, &v, 0); - if (*v == 0) - return ARITH_NUM; - } - error("arith: syntax error: \"%s\"", arith_startbuf); - } - YY_BREAK -case 6: -YY_RULE_SETUP -#line 73 "arith_lex.l" -{ return(ARITH_LPAREN); } - YY_BREAK -case 7: -YY_RULE_SETUP -#line 74 "arith_lex.l" -{ return(ARITH_RPAREN); } - YY_BREAK -case 8: -YY_RULE_SETUP -#line 75 "arith_lex.l" -{ return(ARITH_OR); } - YY_BREAK -case 9: -YY_RULE_SETUP -#line 76 "arith_lex.l" -{ return(ARITH_AND); } - YY_BREAK -case 10: -YY_RULE_SETUP -#line 77 "arith_lex.l" -{ return(ARITH_BOR); } - YY_BREAK -case 11: -YY_RULE_SETUP -#line 78 "arith_lex.l" -{ return(ARITH_BXOR); } - YY_BREAK -case 12: -YY_RULE_SETUP -#line 79 "arith_lex.l" -{ return(ARITH_BAND); } - YY_BREAK -case 13: -YY_RULE_SETUP -#line 80 "arith_lex.l" -{ return(ARITH_EQ); } - YY_BREAK -case 14: -YY_RULE_SETUP -#line 81 "arith_lex.l" -{ return(ARITH_NE); } - YY_BREAK -case 15: -YY_RULE_SETUP -#line 82 "arith_lex.l" -{ return(ARITH_GT); } - YY_BREAK -case 16: -YY_RULE_SETUP -#line 83 "arith_lex.l" -{ return(ARITH_GE); } - YY_BREAK -case 17: -YY_RULE_SETUP -#line 84 "arith_lex.l" -{ return(ARITH_LT); } - YY_BREAK -case 18: -YY_RULE_SETUP -#line 85 "arith_lex.l" -{ return(ARITH_LE); } - YY_BREAK -case 19: -YY_RULE_SETUP -#line 86 "arith_lex.l" -{ return(ARITH_LSHIFT); } - YY_BREAK -case 20: -YY_RULE_SETUP -#line 87 "arith_lex.l" -{ return(ARITH_RSHIFT); } - YY_BREAK -case 21: -YY_RULE_SETUP -#line 88 "arith_lex.l" -{ return(ARITH_MUL); } - YY_BREAK -case 22: -YY_RULE_SETUP -#line 89 "arith_lex.l" -{ return(ARITH_DIV); } - YY_BREAK -case 23: -YY_RULE_SETUP -#line 90 "arith_lex.l" -{ return(ARITH_REM); } - YY_BREAK -case 24: -YY_RULE_SETUP -#line 91 "arith_lex.l" -{ return(ARITH_ADD); } - YY_BREAK -case 25: -YY_RULE_SETUP -#line 92 "arith_lex.l" -{ return(ARITH_SUB); } - YY_BREAK -case 26: -YY_RULE_SETUP -#line 93 "arith_lex.l" -{ return(ARITH_BNOT); } - YY_BREAK -case 27: -YY_RULE_SETUP -#line 94 "arith_lex.l" -{ return(ARITH_NOT); } - YY_BREAK -case 28: -YY_RULE_SETUP -#line 95 "arith_lex.l" -{ error("arith: syntax error: \"%s\"", arith_startbuf); } - YY_BREAK -case 29: -YY_RULE_SETUP -#line 96 "arith_lex.l" -ECHO; - YY_BREAK -#line 915 "arith_lex.c" -case YY_STATE_EOF(INITIAL): - yyterminate(); - - case YY_END_OF_BUFFER: - { - /* Amount of text matched not including the EOB char. */ - int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; - - /* Undo the effects of YY_DO_BEFORE_ACTION. */ - *yy_cp = (yy_hold_char); - YY_RESTORE_YY_MORE_OFFSET - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) - { - /* We're scanning a new file or input source. It's - * possible that this happened because the user - * just pointed yyin at a new source and called - * yylex(). If so, then we have to assure - * consistency between YY_CURRENT_BUFFER and our - * globals. Here is the right place to do so, because - * this is the first action (other than possibly a - * back-up) that will match for the new input source. - */ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; - } - - /* Note that here we test for yy_c_buf_p "<=" to the position - * of the first EOB in the buffer, since yy_c_buf_p will - * already have been incremented past the NUL character - * (since all states make transitions on EOB to the - * end-of-buffer state). Contrast this with the test - * in input(). - */ - if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - { /* This was really a NUL. */ - yy_state_type yy_next_state; - - (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - /* Okay, we're now positioned to make the NUL - * transition. We couldn't have - * yy_get_previous_state() go ahead and do it - * for us because it doesn't know how to deal - * with the possibility of jamming (and we don't - * want to build jamming into it because then it - * will run more slowly). - */ - - yy_next_state = yy_try_NUL_trans( yy_current_state ); - - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - - if ( yy_next_state ) - { - /* Consume the NUL. */ - yy_cp = ++(yy_c_buf_p); - yy_current_state = yy_next_state; - goto yy_match; - } - - else - { - yy_cp = (yy_c_buf_p); - goto yy_find_action; - } - } - - else switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_END_OF_FILE: - { - (yy_did_buffer_switch_on_eof) = 0; - - if ( yywrap( ) ) - { - /* Note: because we've taken care in - * yy_get_next_buffer() to have set up - * yytext, we can now set up - * yy_c_buf_p so that if some total - * hoser (like flex itself) wants to - * call the scanner after we return the - * YY_NULL, it'll still work - another - * YY_NULL will get returned. - */ - (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; - - yy_act = YY_STATE_EOF(YY_START); - goto do_action; - } - - else - { - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; - } - break; - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = - (yytext_ptr) + yy_amount_of_matched_text; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_match; - - case EOB_ACT_LAST_MATCH: - (yy_c_buf_p) = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; - - yy_current_state = yy_get_previous_state( ); - - yy_cp = (yy_c_buf_p); - yy_bp = (yytext_ptr) + YY_MORE_ADJ; - goto yy_find_action; - } - break; - } - - default: - YY_FATAL_ERROR( - "fatal flex scanner internal error--no action found" ); - } /* end of action switch */ - } /* end of scanning one token */ -} /* end of yylex */ - -/* yy_get_next_buffer - try to read in a new buffer - * - * Returns a code representing an action: - * EOB_ACT_LAST_MATCH - - * EOB_ACT_CONTINUE_SCAN - continue scanning from current position - * EOB_ACT_END_OF_FILE - end of file - */ -static int yy_get_next_buffer (void) -{ - register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; - register char *source = (yytext_ptr); - register int number_to_move, i; - int ret_val; - - if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) - YY_FATAL_ERROR( - "fatal flex scanner internal error--end of buffer missed" ); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) - { /* Don't try to fill the buffer, so this is an EOF. */ - if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) - { - /* We matched a single character, the EOB, so - * treat this as a final EOF. - */ - return EOB_ACT_END_OF_FILE; - } - - else - { - /* We matched some text prior to the EOB, first - * process it. - */ - return EOB_ACT_LAST_MATCH; - } - } - - /* Try to read more data. */ - - /* First move last chars to start of buffer. */ - number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; - - for ( i = 0; i < number_to_move; ++i ) - *(dest++) = *(source++); - - if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) - /* don't do the read, it's not guaranteed to return an EOF, - * just force an EOF - */ - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; - - else - { - size_t num_to_read = - YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; - - while ( num_to_read <= 0 ) - { /* Not enough room in the buffer - grow it. */ - - /* just a shorter name for the current buffer */ - YY_BUFFER_STATE b = YY_CURRENT_BUFFER; - - int yy_c_buf_p_offset = - (int) ((yy_c_buf_p) - b->yy_ch_buf); - - if ( b->yy_is_our_buffer ) - { - int new_size = b->yy_buf_size * 2; - - if ( new_size <= 0 ) - b->yy_buf_size += b->yy_buf_size / 8; - else - b->yy_buf_size *= 2; - - b->yy_ch_buf = (char *) - /* Include room in for 2 EOB chars. */ - yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); - } - else - /* Can't grow it, we don't own it. */ - b->yy_ch_buf = 0; - - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( - "fatal error - scanner input buffer overflow" ); - - (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; - - num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - - number_to_move - 1; - - } - - if ( num_to_read > YY_READ_BUF_SIZE ) - num_to_read = YY_READ_BUF_SIZE; - - /* Read in more data. */ - YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), - (yy_n_chars), num_to_read ); - - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - if ( (yy_n_chars) == 0 ) - { - if ( number_to_move == YY_MORE_ADJ ) - { - ret_val = EOB_ACT_END_OF_FILE; - yyrestart(yyin ); - } - - else - { - ret_val = EOB_ACT_LAST_MATCH; - YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = - YY_BUFFER_EOF_PENDING; - } - } - - else - ret_val = EOB_ACT_CONTINUE_SCAN; - - (yy_n_chars) += number_to_move; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; - - (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; - - return ret_val; -} - -/* yy_get_previous_state - get the state just before the EOB char was reached */ - - static yy_state_type yy_get_previous_state (void) -{ - register yy_state_type yy_current_state; - register char *yy_cp; - - yy_current_state = (yy_start); - - for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) - { - register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 39 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - } - - return yy_current_state; -} - -/* yy_try_NUL_trans - try to make a transition on the NUL character - * - * synopsis - * next_state = yy_try_NUL_trans( current_state ); - */ - static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) -{ - register int yy_is_jam; - register char *yy_cp = (yy_c_buf_p); - - register YY_CHAR yy_c = 1; - if ( yy_accept[yy_current_state] ) - { - (yy_last_accepting_state) = yy_current_state; - (yy_last_accepting_cpos) = yy_cp; - } - while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) - { - yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 39 ) - yy_c = yy_meta[(unsigned int) yy_c]; - } - yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 38); - - return yy_is_jam ? 0 : yy_current_state; -} - - static void yyunput (int c, register char * yy_bp ) -{ - register char *yy_cp; - - yy_cp = (yy_c_buf_p); - - /* undo effects of setting up yytext */ - *yy_cp = (yy_hold_char); - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - { /* need to shift things up to make room */ - /* +2 for EOB chars. */ - register int number_to_move = (yy_n_chars) + 2; - register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ - YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; - register char *source = - &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; - - while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) - *--dest = *--source; - - yy_cp += (int) (dest - source); - yy_bp += (int) (dest - source); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; - - if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) - YY_FATAL_ERROR( "flex scanner push-back overflow" ); - } - - *--yy_cp = (char) c; - - (yytext_ptr) = yy_bp; - (yy_hold_char) = *yy_cp; - (yy_c_buf_p) = yy_cp; -} - -#ifndef YY_NO_INPUT -#ifdef __cplusplus - static int yyinput (void) -#else - static int input (void) -#endif - -{ - int c; - - *(yy_c_buf_p) = (yy_hold_char); - - if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) - { - /* yy_c_buf_p now points to the character we want to return. - * If this occurs *before* the EOB characters, then it's a - * valid NUL; if not, then we've hit the end of the buffer. - */ - if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) - /* This was really a NUL. */ - *(yy_c_buf_p) = '\0'; - - else - { /* need more input */ - int offset = (yy_c_buf_p) - (yytext_ptr); - ++(yy_c_buf_p); - - switch ( yy_get_next_buffer( ) ) - { - case EOB_ACT_LAST_MATCH: - /* This happens because yy_g_n_b() - * sees that we've accumulated a - * token and flags that we need to - * try matching the token before - * proceeding. But for input(), - * there's no matching to consider. - * So convert the EOB_ACT_LAST_MATCH - * to EOB_ACT_END_OF_FILE. - */ - - /* Reset buffer status. */ - yyrestart(yyin ); - - /*FALLTHROUGH*/ - - case EOB_ACT_END_OF_FILE: - { - if ( yywrap( ) ) - return EOF; - - if ( ! (yy_did_buffer_switch_on_eof) ) - YY_NEW_FILE; -#ifdef __cplusplus - return yyinput(); -#else - return input(); -#endif - } - - case EOB_ACT_CONTINUE_SCAN: - (yy_c_buf_p) = (yytext_ptr) + offset; - break; - } - } - } - - c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ - *(yy_c_buf_p) = '\0'; /* preserve yytext */ - (yy_hold_char) = *++(yy_c_buf_p); - - return c; -} -#endif /* ifndef YY_NO_INPUT */ - -/** Immediately switch to a different input stream. - * @param input_file A readable stream. - * - * @note This function does not reset the start condition to @c INITIAL . - */ - void yyrestart (FILE * input_file ) -{ - - if ( ! YY_CURRENT_BUFFER ){ - yyensure_buffer_stack (); - YY_CURRENT_BUFFER_LVALUE = - yy_create_buffer(yyin,YY_BUF_SIZE ); - } - - yy_init_buffer(YY_CURRENT_BUFFER,input_file ); - yy_load_buffer_state( ); -} - -/** Switch to a different input buffer. - * @param new_buffer The new input buffer. - * - */ - void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) -{ - - /* TODO. We should be able to replace this entire function body - * with - * yypop_buffer_state(); - * yypush_buffer_state(new_buffer); - */ - yyensure_buffer_stack (); - if ( YY_CURRENT_BUFFER == new_buffer ) - return; - - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - YY_CURRENT_BUFFER_LVALUE = new_buffer; - yy_load_buffer_state( ); - - /* We don't actually know whether we did this switch during - * EOF (yywrap()) processing, but the only time this flag - * is looked at is after yywrap() is called, so it's safe - * to go ahead and always set it. - */ - (yy_did_buffer_switch_on_eof) = 1; -} - -static void yy_load_buffer_state (void) -{ - (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; - (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; - yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; - (yy_hold_char) = *(yy_c_buf_p); -} - -/** Allocate and initialize an input buffer state. - * @param file A readable stream. - * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. - * - * @return the allocated buffer state. - */ - YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) -{ - YY_BUFFER_STATE b; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_buf_size = size; - - /* yy_ch_buf has to be 2 characters longer than the size given because - * we need to put in 2 end-of-buffer characters. - */ - b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); - if ( ! b->yy_ch_buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); - - b->yy_is_our_buffer = 1; - - yy_init_buffer(b,file ); - - return b; -} - -/** Destroy the buffer. - * @param b a buffer created with yy_create_buffer() - * - */ - void yy_delete_buffer (YY_BUFFER_STATE b ) -{ - - if ( ! b ) - return; - - if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ - YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; - - if ( b->yy_is_our_buffer ) - yyfree((void *) b->yy_ch_buf ); - - yyfree((void *) b ); -} - -#ifndef __cplusplus -extern int isatty (int ); -#endif /* __cplusplus */ - -/* Initializes or reinitializes a buffer. - * This function is sometimes called more than once on the same buffer, - * such as during a yyrestart() or at EOF. - */ - static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) - -{ - int oerrno = errno; - - yy_flush_buffer(b ); - - b->yy_input_file = file; - b->yy_fill_buffer = 1; - - /* If b is the current buffer, then yy_init_buffer was _probably_ - * called from yyrestart() or through yy_get_next_buffer. - * In that case, we don't want to reset the lineno or column. - */ - if (b != YY_CURRENT_BUFFER){ - b->yy_bs_lineno = 1; - b->yy_bs_column = 0; - } - - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; - - errno = oerrno; -} - -/** Discard all buffered characters. On the next scan, YY_INPUT will be called. - * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. - * - */ - void yy_flush_buffer (YY_BUFFER_STATE b ) -{ - if ( ! b ) - return; - - b->yy_n_chars = 0; - - /* We always need two end-of-buffer characters. The first causes - * a transition to the end-of-buffer state. The second causes - * a jam in that state. - */ - b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; - b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; - - b->yy_buf_pos = &b->yy_ch_buf[0]; - - b->yy_at_bol = 1; - b->yy_buffer_status = YY_BUFFER_NEW; - - if ( b == YY_CURRENT_BUFFER ) - yy_load_buffer_state( ); -} - -/** Pushes the new state onto the stack. The new state becomes - * the current state. This function will allocate the stack - * if necessary. - * @param new_buffer The new state. - * - */ -void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) -{ - if (new_buffer == NULL) - return; - - yyensure_buffer_stack(); - - /* This block is copied from yy_switch_to_buffer. */ - if ( YY_CURRENT_BUFFER ) - { - /* Flush out information for old buffer. */ - *(yy_c_buf_p) = (yy_hold_char); - YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); - YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); - } - - /* Only push if top exists. Otherwise, replace top. */ - if (YY_CURRENT_BUFFER) - (yy_buffer_stack_top)++; - YY_CURRENT_BUFFER_LVALUE = new_buffer; - - /* copied from yy_switch_to_buffer. */ - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; -} - -/** Removes and deletes the top of the stack, if present. - * The next element becomes the new top. - * - */ -void yypop_buffer_state (void) -{ - if (!YY_CURRENT_BUFFER) - return; - - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - if ((yy_buffer_stack_top) > 0) - --(yy_buffer_stack_top); - - if (YY_CURRENT_BUFFER) { - yy_load_buffer_state( ); - (yy_did_buffer_switch_on_eof) = 1; - } -} - -/* Allocates the stack if it does not exist. - * Guarantees space for at least one push. - */ -static void yyensure_buffer_stack (void) -{ - int num_to_alloc; - - if (!(yy_buffer_stack)) { - - /* First allocation is just for 2 elements, since we don't know if this - * scanner will even need a stack. We use 2 instead of 1 to avoid an - * immediate realloc on the next call. - */ - num_to_alloc = 1; - (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc - (num_to_alloc * sizeof(struct yy_buffer_state*) - ); - - memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); - - (yy_buffer_stack_max) = num_to_alloc; - (yy_buffer_stack_top) = 0; - return; - } - - if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ - - /* Increase the buffer to prepare for a possible push. */ - int grow_size = 8 /* arbitrary grow size */; - - num_to_alloc = (yy_buffer_stack_max) + grow_size; - (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc - ((yy_buffer_stack), - num_to_alloc * sizeof(struct yy_buffer_state*) - ); - - /* zero only the new slots.*/ - memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); - (yy_buffer_stack_max) = num_to_alloc; - } -} - -/** Setup the input buffer state to scan directly from a user-specified character buffer. - * @param base the character buffer - * @param size the size in bytes of the character buffer - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) -{ - YY_BUFFER_STATE b; - - if ( size < 2 || - base[size-2] != YY_END_OF_BUFFER_CHAR || - base[size-1] != YY_END_OF_BUFFER_CHAR ) - /* They forgot to leave room for the EOB's. */ - return 0; - - b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); - if ( ! b ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); - - b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ - b->yy_buf_pos = b->yy_ch_buf = base; - b->yy_is_our_buffer = 0; - b->yy_input_file = 0; - b->yy_n_chars = b->yy_buf_size; - b->yy_is_interactive = 0; - b->yy_at_bol = 1; - b->yy_fill_buffer = 0; - b->yy_buffer_status = YY_BUFFER_NEW; - - yy_switch_to_buffer(b ); - - return b; -} - -/** Setup the input buffer state to scan a string. The next call to yylex() will - * scan from a @e copy of @a str. - * @param str a NUL-terminated string to scan - * - * @return the newly allocated buffer state object. - * @note If you want to scan bytes that may contain NUL values, then use - * yy_scan_bytes() instead. - */ -YY_BUFFER_STATE yy_scan_string (yyconst char * yy_str ) -{ - - return yy_scan_bytes(yy_str,strlen(yy_str) ); -} - -/** Setup the input buffer state to scan the given bytes. The next call to yylex() will - * scan from a @e copy of @a bytes. - * @param bytes the byte buffer to scan - * @param len the number of bytes in the buffer pointed to by @a bytes. - * - * @return the newly allocated buffer state object. - */ -YY_BUFFER_STATE yy_scan_bytes (yyconst char * bytes, int len ) -{ - YY_BUFFER_STATE b; - char *buf; - yy_size_t n; - int i; - - /* Get memory for full buffer, including space for trailing EOB's. */ - n = len + 2; - buf = (char *) yyalloc(n ); - if ( ! buf ) - YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); - - for ( i = 0; i < len; ++i ) - buf[i] = bytes[i]; - - buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; - - b = yy_scan_buffer(buf,n ); - if ( ! b ) - YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); - - /* It's okay to grow etc. this buffer, and we should throw it - * away when we're done. - */ - b->yy_is_our_buffer = 1; - - return b; -} - -#ifndef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#endif - -static void yy_fatal_error (yyconst char* msg ) -{ - (void) fprintf( stderr, "%s\n", msg ); - exit( YY_EXIT_FAILURE ); -} - -/* Redefine yyless() so it works in section 3 code. */ - -#undef yyless -#define yyless(n) \ - do \ - { \ - /* Undo effects of setting up yytext. */ \ - int yyless_macro_arg = (n); \ - YY_LESS_LINENO(yyless_macro_arg);\ - yytext[yyleng] = (yy_hold_char); \ - (yy_c_buf_p) = yytext + yyless_macro_arg; \ - (yy_hold_char) = *(yy_c_buf_p); \ - *(yy_c_buf_p) = '\0'; \ - yyleng = yyless_macro_arg; \ - } \ - while ( 0 ) - -/* Accessor methods (get/set functions) to struct members. */ - -/** Get the current line number. - * - */ -int yyget_lineno (void) -{ - - return yylineno; -} - -/** Get the input stream. - * - */ -FILE *yyget_in (void) -{ - return yyin; -} - -/** Get the output stream. - * - */ -FILE *yyget_out (void) -{ - return yyout; -} - -/** Get the length of the current token. - * - */ -int yyget_leng (void) -{ - return yyleng; -} - -/** Get the current token. - * - */ - -char *yyget_text (void) -{ - return yytext; -} - -/** Set the current line number. - * @param line_number - * - */ -void yyset_lineno (int line_number ) -{ - - yylineno = line_number; -} - -/** Set the input stream. This does not discard the current - * input buffer. - * @param in_str A readable stream. - * - * @see yy_switch_to_buffer - */ -void yyset_in (FILE * in_str ) -{ - yyin = in_str ; -} - -void yyset_out (FILE * out_str ) -{ - yyout = out_str ; -} - -int yyget_debug (void) -{ - return yy_flex_debug; -} - -void yyset_debug (int bdebug ) -{ - yy_flex_debug = bdebug ; -} - -/* yylex_destroy is for both reentrant and non-reentrant scanners. */ -int yylex_destroy (void) -{ - - /* Pop the buffer stack, destroying each element. */ - while(YY_CURRENT_BUFFER){ - yy_delete_buffer(YY_CURRENT_BUFFER ); - YY_CURRENT_BUFFER_LVALUE = NULL; - yypop_buffer_state(); - } - - /* Destroy the stack itself. */ - yyfree((yy_buffer_stack) ); - (yy_buffer_stack) = NULL; - - return 0; -} - -/* - * Internal utility routines. - */ - -#ifndef yytext_ptr -static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) -{ - register int i; - for ( i = 0; i < n; ++i ) - s1[i] = s2[i]; -} -#endif - -#ifdef YY_NEED_STRLEN -static int yy_flex_strlen (yyconst char * s ) -{ - register int n; - for ( n = 0; s[n]; ++n ) - ; - - return n; -} -#endif - -void *yyalloc (yy_size_t size ) -{ - return (void *) malloc( size ); -} - -void *yyrealloc (void * ptr, yy_size_t size ) -{ - /* The cast to (char *) in the following accommodates both - * implementations that use char* generic pointers, and those - * that use void* generic pointers. It works with the latter - * because both ANSI C and C++ allow castless assignment from - * any pointer type to void*, and deal with argument conversions - * as though doing an assignment. - */ - return (void *) realloc( (char *) ptr, size ); -} - -void yyfree (void * ptr ) -{ - free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ -} - -#define YYTABLES_NAME "yytables" - -#undef YY_NEW_FILE -#undef YY_FLUSH_BUFFER -#undef yy_set_bol -#undef yy_new_buffer -#undef yy_set_interactive -#undef yytext_ptr -#undef YY_DO_BEFORE_ACTION - -#ifdef YY_DECL_IS_OURS -#undef YY_DECL_IS_OURS -#undef YY_DECL -#endif -#line 96 "arith_lex.l" - - - -void -arith_lex_reset() { -#ifdef YY_NEW_FILE - YY_NEW_FILE; -#endif -} - diff --git a/sh/arith_lex.l b/sh/arith_lex.l deleted file mode 100644 index 79116fca369f50f0c61e156cc5cfc7e7e106ec8a..0000000000000000000000000000000000000000 --- a/sh/arith_lex.l +++ /dev/null @@ -1,103 +0,0 @@ -%{ -/* $NetBSD: arith_lex.l,v 1.12.6.1 2005/04/07 11:38:58 tron Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: arith_lex.l,v 1.12.6.1 2005/04/07 11:38:58 tron Exp $"); -#endif -#endif /* not lint */ - -#include <unistd.h> -#include "arith.h" -#include "error.h" -#include "expand.h" -#include "var.h" - -extern int yylval; -extern char *arith_buf, *arith_startbuf; -#undef YY_INPUT -#define YY_INPUT(buf,result,max) \ - result = (*buf = *arith_buf++) ? 1 : YY_NULL; -#define YY_NO_UNPUT -%} -%option noyywrap - -%% -[ \t\n] { ; } -0x[0-9a-fA-F]+ { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } -0[0-7]* { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } -[1-9][0-9]* { yylval = strtol(yytext, 0, 0); return(ARITH_NUM); } -[A-Za-z_][A-Za-z_0-9]* { char *v = lookupvar(yytext); - if (v) { - yylval = strtol(v, &v, 0); - if (*v == 0) - return ARITH_NUM; - } - error("arith: syntax error: \"%s\"", arith_startbuf); - } -"(" { return(ARITH_LPAREN); } -")" { return(ARITH_RPAREN); } -"||" { return(ARITH_OR); } -"&&" { return(ARITH_AND); } -"|" { return(ARITH_BOR); } -"^" { return(ARITH_BXOR); } -"&" { return(ARITH_BAND); } -"==" { return(ARITH_EQ); } -"!=" { return(ARITH_NE); } -">" { return(ARITH_GT); } -">=" { return(ARITH_GE); } -"<" { return(ARITH_LT); } -"<=" { return(ARITH_LE); } -"<<" { return(ARITH_LSHIFT); } -">>" { return(ARITH_RSHIFT); } -"*" { return(ARITH_MUL); } -"/" { return(ARITH_DIV); } -"%" { return(ARITH_REM); } -"+" { return(ARITH_ADD); } -"-" { return(ARITH_SUB); } -"~" { return(ARITH_BNOT); } -"!" { return(ARITH_NOT); } -. { error("arith: syntax error: \"%s\"", arith_startbuf); } -%% - -void -arith_lex_reset() { -#ifdef YY_NEW_FILE - YY_NEW_FILE; -#endif -} diff --git a/sh/bltin/bltin.h b/sh/bltin/bltin.h deleted file mode 100644 index b8f9d750fc71cbad9325886927d2abc3cc5b74a0..0000000000000000000000000000000000000000 --- a/sh/bltin/bltin.h +++ /dev/null @@ -1,94 +0,0 @@ -/* $NetBSD: bltin.h,v 1.11 2003/08/07 09:05:40 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)bltin.h 8.1 (Berkeley) 5/31/93 - */ - -/* - * This file is included by programs which are optionally built into the - * shell. If SHELL is defined, we try to map the standard UNIX library - * routines to ash routines using defines. - */ - -#include "../shell.h" -#include "../mystring.h" -#ifdef SHELL -#include "../output.h" -#include "../error.h" -#undef stdout -#undef stderr -#undef putc -#undef putchar -#undef fileno -#define stdout out1 -#define stderr out2 -#define printf out1fmt -#define putc(c, file) outc(c, file) -#define putchar(c) out1c(c) -#define FILE struct output -#define fprintf outfmt -#define fputs outstr -#define fflush flushout -#define fileno(f) ((f)->fd) -#define INITARGS(argv) -#define err sh_err -#define verr sh_verr -#define errx sh_errx -#define verrx sh_verrx -#define warn sh_warn -#define vwarn sh_vwarn -#define warnx sh_warnx -#define vwarnx sh_vwarnx -#define exit sh_exit -#define setprogname(s) -#define getprogname() commandname -#define setlocate(l,s) 0 - -#define getenv(p) bltinlookup((p),0) - -#else -#undef NULL -#include <stdio.h> -#undef main -#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else -#endif - -pointer stalloc(int); -void error(const char *, ...); -void sh_warnx(const char *, ...); -void sh_exit(int) __attribute__((__noreturn__)); - -int echocmd(int, char **); - - -extern const char *commandname; diff --git a/sh/bltin/echo.1 b/sh/bltin/echo.1 deleted file mode 100644 index 7e71fa336ace9c631de15c810105772e16fb234b..0000000000000000000000000000000000000000 --- a/sh/bltin/echo.1 +++ /dev/null @@ -1,109 +0,0 @@ -.\" $NetBSD: echo.1,v 1.13 2003/08/07 09:05:40 agc Exp $ -.\" -.\" Copyright (c) 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Kenneth Almquist. -.\" Copyright 1989 by Kenneth Almquist -.\" -.\" 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. -.\" 3. 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. -.\" -.\" @(#)echo.1 8.1 (Berkeley) 5/31/93 -.\" -.Dd May 31, 1993 -.Dt ECHO 1 -.Os -.Sh NAME -.Nm echo -.Nd produce message in a shell script -.Sh SYNOPSIS -.Nm -.Op Fl n | Fl e -.Ar args ... -.Sh DESCRIPTION -.Nm -prints its arguments on the standard output, separated by spaces. -Unless the -.Fl n -option is present, a newline is output following the arguments. -The -.Fl e -option causes -.Nm -to treat the escape sequences specially, as described in the following -paragraph. -The -.Fl e -option is the default, and is provided solely for compatibility with -other systems. -Only one of the options -.Fl n -and -.Fl e -may be given. -.Pp -If any of the following sequences of characters is encountered during -output, the sequence is not output. Instead, the specified action is -performed: -.Bl -tag -width indent -.It Li \eb -A backspace character is output. -.It Li \ec -Subsequent output is suppressed. This is normally used at the end of the -last argument to suppress the trailing newline that -.Nm -would otherwise output. -.It Li \ef -Output a form feed. -.It Li \en -Output a newline character. -.It Li \er -Output a carriage return. -.It Li \et -Output a (horizontal) tab character. -.It Li \ev -Output a vertical tab. -.It Li \e0 Ns Ar digits -Output the character whose value is given by zero to three digits. -If there are zero digits, a nul character is output. -.It Li \e\e -Output a backslash. -.El -.Sh HINTS -Remember that backslash is special to the shell and needs to be escaped. -To output a message to standard error, say -.Pp -.D1 echo message \*[Gt]\*[Am]2 -.Sh BUGS -The octal character escape mechanism -.Pq Li \e0 Ns Ar digits -differs from the -C language mechanism. -.Pp -There is no way to force -.Nm -to treat its arguments literally, rather than interpreting them as -options and escape sequences. diff --git a/sh/bltin/echo.c b/sh/bltin/echo.c deleted file mode 100644 index bed75358c84c10c5778c2ad49edaa562a791b8b6..0000000000000000000000000000000000000000 --- a/sh/bltin/echo.c +++ /dev/null @@ -1,116 +0,0 @@ -/* $NetBSD: echo.c,v 1.12 2005/02/06 04:43:43 perry Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)echo.c 8.1 (Berkeley) 5/31/93 - */ - -/* - * Echo command. - * - * echo is steeped in tradition - several of them! - * netbsd has supported 'echo [-n | -e] args' in spite of -e not being - * documented anywhere. - * Posix requires that -n be supported, output from strings containing - * \ is implementation defined - * The Single Unix Spec requires that \ escapes be treated as if -e - * were set, but that -n not be treated as an option. - * (ksh supports 'echo [-eEn] args', but not -- so that it is actually - * impossible to actually output '-n') - * - * It is suggested that 'printf "%b" "string"' be used to get \ sequences - * expanded. printf is now a builtin of netbsd's sh and csh. - */ - -//#define main echocmd - -#include "bltin.h" - -int -echocmd(int argc, char **argv) -{ - char **ap; - char *p; - char c; - int count; - int nflag = 0; - int eflag = 0; - - ap = argv; - if (argc) - ap++; - - if ((p = *ap) != NULL) { - if (equal(p, "-n")) { - nflag = 1; - ap++; - } else if (equal(p, "-e")) { - eflag = 1; - ap++; - } - } - - while ((p = *ap++) != NULL) { - while ((c = *p++) != '\0') { - if (c == '\\' && eflag) { - switch (*p++) { - case 'a': c = '\a'; break; /* bell */ - case 'b': c = '\b'; break; - case 'c': return 0; /* exit */ - case 'e': c = 033; break; /* escape */ - case 'f': c = '\f'; break; - case 'n': c = '\n'; break; - case 'r': c = '\r'; break; - case 't': c = '\t'; break; - case 'v': c = '\v'; break; - case '\\': break; /* c = '\\' */ - case '0': - c = 0; - count = 3; - while (--count >= 0 && (unsigned)(*p - '0') < 8) - c = (c << 3) + (*p++ - '0'); - break; - default: - /* Output the '/' and char following */ - p--; - break; - } - } - putchar(c); - } - if (*ap) - putchar(' '); - } - if (! nflag) - putchar('\n'); - return 0; -} diff --git a/sh/builtins.c b/sh/builtins.c deleted file mode 100644 index 344dbd6229e1ba072edf6a24f3fff501e9eb0f93..0000000000000000000000000000000000000000 --- a/sh/builtins.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * This file was generated by the mkbuiltins program. - */ - -#include "shell.h" -#include "builtins.h" - -const struct builtincmd builtincmd[] = { - - { "command", bltincmd }, - { "bg", bgcmd }, - { "cd", cdcmd }, - { "chdir", cdcmd }, - { "echo", echocmd }, - { "exp", expcmd }, - { "let", expcmd }, - { "false", falsecmd }, -#if WITH_HISTORY - { "fc", histcmd }, - { "inputrc", inputrc }, -#endif - { "fg", fgcmd }, - { "getopts", getoptscmd }, - { "hash", hashcmd }, - { "jobid", jobidcmd }, - { "jobs", jobscmd }, - { "local", localcmd }, -#ifndef SMALL -#endif - { "pwd", pwdcmd }, - { "read", readcmd }, - { "setvar", setvarcmd }, - { "true", truecmd }, - { "type", typecmd }, - { "umask", umaskcmd }, - { "unalias", unaliascmd }, - { "wait", waitcmd }, - { "alias", aliascmd }, - { "ulimit", ulimitcmd }, - { "wordexp", wordexpcmd }, - { 0, 0 }, -}; - -const struct builtincmd splbltincmd[] = { - { "break", breakcmd }, - { "continue", breakcmd }, - { ".", dotcmd }, - { "eval", evalcmd }, - { "exec", execcmd }, - { "exit", exitcmd }, - { "export", exportcmd }, - { "readonly", exportcmd }, - { "return", returncmd }, - { "set", setcmd }, - { "shift", shiftcmd }, - { "times", timescmd }, - { "trap", trapcmd }, - { ":", truecmd }, - { "unset", unsetcmd }, - { 0, 0 }, -}; diff --git a/sh/builtins.def b/sh/builtins.def deleted file mode 100644 index 18e56c60bb28c4d5d73764af427411d40e1df3fb..0000000000000000000000000000000000000000 --- a/sh/builtins.def +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/sh - -# $NetBSD: builtins.def,v 1.21 2004/07/13 15:05:59 seb Exp $ -# -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. 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. -# -# @(#)builtins.def 8.4 (Berkeley) 5/4/95 - -# -# This file lists all the builtin commands. The first column is the name -# of a C routine. -# The -j flag specifies that this command is to be excluded from systems -# without job control. -# The -h flag specifies that this command is to be excluded from systems -# based on the SMALL compile-time symbol. -# The -s flag specifies that this is a posix 'special builtin' command. -# The -u flag specifies that this is a posix 'standard utility'. -# The rest of the line specifies the command name or names used to run -# the command. - -bltincmd -u command -bgcmd -j -u bg -breakcmd -s break -s continue -cdcmd -u cd chdir -dotcmd -s . -echocmd echo -evalcmd -s eval -execcmd -s exec -exitcmd -s exit -expcmd exp let -exportcmd -s export -s readonly -falsecmd -u false -#if WITH_HISTORY -histcmd -h -u fc -inputrc inputrc -#endif -fgcmd -j -u fg -getoptscmd -u getopts -hashcmd hash -jobidcmd jobid -jobscmd -u jobs -localcmd local -#ifndef SMALL -##printfcmd printf -#endif -pwdcmd -u pwd -readcmd -u read -returncmd -s return -setcmd -s set -setvarcmd setvar -shiftcmd -s shift -timescmd -s times -trapcmd -s trap -truecmd -s : -u true -typecmd type -umaskcmd -u umask -unaliascmd -u unalias -unsetcmd -s unset -waitcmd -u wait -aliascmd -u alias -ulimitcmd ulimit -##testcmd test [ -##killcmd -u kill # mandated by posix for 'kill %job' -wordexpcmd wordexp -#newgrp -u newgrp # optional command in posix - -#exprcmd expr diff --git a/sh/builtins.h b/sh/builtins.h deleted file mode 100644 index 1f9e45a519adbdf191a700cbb1b0f44fbb722c38..0000000000000000000000000000000000000000 --- a/sh/builtins.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * This file was generated by the mkbuiltins program. - */ - -#include <sys/cdefs.h> - -struct builtincmd { - const char *name; - int (*builtin)(int, char **); -}; - -extern const struct builtincmd builtincmd[]; -extern const struct builtincmd splbltincmd[]; - - -int bltincmd(int, char **); -int bgcmd(int, char **); -int breakcmd(int, char **); -int cdcmd(int, char **); -int dotcmd(int, char **); -int echocmd(int, char **); -int evalcmd(int, char **); -int execcmd(int, char **); -int exitcmd(int, char **); -int expcmd(int, char **); -int exportcmd(int, char **); -int falsecmd(int, char **); -#if WITH_HISTORY -int histcmd(int, char **); -int inputrc(int, char **); -#endif -int fgcmd(int, char **); -int getoptscmd(int, char **); -int hashcmd(int, char **); -int jobidcmd(int, char **); -int jobscmd(int, char **); -int localcmd(int, char **); -#ifndef SMALL -#endif -int pwdcmd(int, char **); -int readcmd(int, char **); -int returncmd(int, char **); -int setcmd(int, char **); -int setvarcmd(int, char **); -int shiftcmd(int, char **); -int timescmd(int, char **); -int trapcmd(int, char **); -int truecmd(int, char **); -int typecmd(int, char **); -int umaskcmd(int, char **); -int unaliascmd(int, char **); -int unsetcmd(int, char **); -int waitcmd(int, char **); -int aliascmd(int, char **); -int ulimitcmd(int, char **); -int wordexpcmd(int, char **); diff --git a/sh/cd.c b/sh/cd.c deleted file mode 100644 index 4ab599b2455796e05314bcc2465e8e842f2a8016..0000000000000000000000000000000000000000 --- a/sh/cd.c +++ /dev/null @@ -1,446 +0,0 @@ -/* $NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: cd.c,v 1.34 2003/11/14 20:00:28 dsl Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <errno.h> - -/* - * The cd and pwd commands. - */ - -#include "shell.h" -#include "var.h" -#include "nodes.h" /* for jobs.h */ -#include "jobs.h" -#include "options.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "exec.h" -#include "redir.h" -#include "mystring.h" -#include "show.h" -#include "cd.h" - -STATIC int docd(char *, int); -STATIC char *getcomponent(void); -STATIC void updatepwd(char *); -STATIC void find_curdir(int noerror); - -char *curdir = NULL; /* current working directory */ -char *prevdir; /* previous working directory */ -STATIC char *cdcomppath; - -int -cdcmd(int argc, char **argv) -{ - const char *dest; - const char *path; - char *p, *d; - struct stat statb; - int print = cdprint; /* set -cdprint to enable */ - - nextopt(nullstr); - - /* - * Try (quite hard) to have 'curdir' defined, nothing has set - * it on entry to the shell, but we want 'cd fred; cd -' to work. - */ - getpwd(1); - dest = *argptr; - if (dest == NULL) { - dest = bltinlookup("HOME", 1); - if (dest == NULL) - error("HOME not set"); - } else { - if (argptr[1]) { - /* Do 'ksh' style substitution */ - if (!curdir) - error("PWD not set"); - p = strstr(curdir, dest); - if (!p) - error("bad substitution"); - d = stalloc(strlen(curdir) + strlen(argptr[1]) + 1); - memcpy(d, curdir, p - curdir); - strcpy(d + (p - curdir), argptr[1]); - strcat(d, p + strlen(dest)); - dest = d; - print = 1; - } - } - - if (dest[0] == '-' && dest[1] == '\0') { - dest = prevdir ? prevdir : curdir; - print = 1; - } - if (*dest == '\0') - dest = "."; - if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL) - path = nullstr; - while ((p = padvance(&path, dest)) != NULL) { - if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { - if (!print) { - /* - * XXX - rethink - */ - if (p[0] == '.' && p[1] == '/' && p[2] != '\0') - p += 2; - print = strcmp(p, dest); - } - if (docd(p, print) >= 0) - return 0; - - } - } - error("can't cd to %s", dest); - /* NOTREACHED */ -} - - -/* - * Actually do the chdir. In an interactive shell, print the - * directory name if "print" is nonzero. - */ - -STATIC int -docd(char *dest, int print) -{ - char *p; - char *q; - char *component; - struct stat statb; - int first; - int badstat; - - TRACE(("docd(\"%s\", %d) called\n", dest, print)); - - /* - * Check each component of the path. If we find a symlink or - * something we can't stat, clear curdir to force a getcwd() - * next time we get the value of the current directory. - */ - badstat = 0; - cdcomppath = stalloc(strlen(dest) + 1); - scopy(dest, cdcomppath); - STARTSTACKSTR(p); - if (*dest == '/') { - STPUTC('/', p); - cdcomppath++; - } - first = 1; - while ((q = getcomponent()) != NULL) { - if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) - continue; - if (! first) - STPUTC('/', p); - first = 0; - component = q; - while (*q) - STPUTC(*q++, p); - if (equal(component, "..")) - continue; - STACKSTRNUL(p); - if ((lstat(stackblock(), &statb) < 0) - || (S_ISLNK(statb.st_mode))) { - /* print = 1; */ - badstat = 1; - break; - } - } - - INTOFF; - if (chdir(dest) < 0) { - INTON; - return -1; - } - updatepwd(badstat ? NULL : dest); - INTON; - if (print && iflag && curdir) - out1fmt("%s\n", curdir); - return 0; -} - - -/* - * Get the next component of the path name pointed to by cdcomppath. - * This routine overwrites the string pointed to by cdcomppath. - */ - -STATIC char * -getcomponent() -{ - char *p; - char *start; - - if ((p = cdcomppath) == NULL) - return NULL; - start = cdcomppath; - while (*p != '/' && *p != '\0') - p++; - if (*p == '\0') { - cdcomppath = NULL; - } else { - *p++ = '\0'; - cdcomppath = p; - } - return start; -} - - - -/* - * Update curdir (the name of the current directory) in response to a - * cd command. We also call hashcd to let the routines in exec.c know - * that the current directory has changed. - */ - -STATIC void -updatepwd(char *dir) -{ - char *new; - char *p; - - hashcd(); /* update command hash table */ - - /* - * If our argument is NULL, we don't know the current directory - * any more because we traversed a symbolic link or something - * we couldn't stat(). - */ - if (dir == NULL || curdir == NULL) { - if (prevdir) - ckfree(prevdir); - INTOFF; - prevdir = curdir; - curdir = NULL; - getpwd(1); - INTON; - if (curdir) - setvar("PWD", curdir, VEXPORT); - else - unsetvar("PWD", 0); - return; - } - cdcomppath = stalloc(strlen(dir) + 1); - scopy(dir, cdcomppath); - STARTSTACKSTR(new); - if (*dir != '/') { - p = curdir; - while (*p) - STPUTC(*p++, new); - if (p[-1] == '/') - STUNPUTC(new); - } - while ((p = getcomponent()) != NULL) { - if (equal(p, "..")) { - while (new > stackblock() && (STUNPUTC(new), *new) != '/'); - } else if (*p != '\0' && ! equal(p, ".")) { - STPUTC('/', new); - while (*p) - STPUTC(*p++, new); - } - } - if (new == stackblock()) - STPUTC('/', new); - STACKSTRNUL(new); - INTOFF; - if (prevdir) - ckfree(prevdir); - prevdir = curdir; - curdir = savestr(stackblock()); - setvar("PWD", curdir, VEXPORT); - INTON; -} - -/* - * Posix says the default should be 'pwd -L' (as below), however - * the 'cd' command (above) does something much nearer to the - * posix 'cd -P' (not the posix default of 'cd -L'). - * If 'cd' is changed to support -P/L then the default here - * needs to be revisited if the historic behaviour is to be kept. - */ - -int -pwdcmd(int argc, char **argv) -{ - int i; - char opt = 'L'; - - while ((i = nextopt("LP")) != '\0') - opt = i; - if (*argptr) - error("unexpected argument"); - - if (opt == 'L') - getpwd(0); - else - find_curdir(0); - - setvar("PWD", curdir, VEXPORT); - out1str(curdir); - out1c('\n'); - return 0; -} - - - - -#define MAXPWD 256 - -/* - * Find out what the current directory is. If we already know the current - * directory, this routine returns immediately. - */ -void -getpwd(int noerror) -{ - char *pwd; - struct stat stdot, stpwd; - static int first = 1; - - if (curdir) - return; - - if (first) { - first = 0; - pwd = getenv("PWD"); - if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && - stat(pwd, &stpwd) != -1 && - stdot.st_dev == stpwd.st_dev && - stdot.st_ino == stpwd.st_ino) { - curdir = savestr(pwd); - return; - } - } - - find_curdir(noerror); - - return; -} - -STATIC void -find_curdir(int noerror) -{ - int i; - char *pwd; - - /* - * Things are a bit complicated here; we could have just used - * getcwd, but traditionally getcwd is implemented using popen - * to /bin/pwd. This creates a problem for us, since we cannot - * keep track of the job if it is being ran behind our backs. - * So we re-implement getcwd(), and we suppress interrupts - * throughout the process. This is not completely safe, since - * the user can still break out of it by killing the pwd program. - * We still try to use getcwd for systems that we know have a - * c implementation of getcwd, that does not open a pipe to - * /bin/pwd. - */ -#if defined(__NetBSD__) || defined(__SVR4) || defined(__linux__) - for (i = MAXPWD;; i *= 2) { - pwd = stalloc(i); - if (getcwd(pwd, i) != NULL) { - curdir = savestr(pwd); - return; - } - stunalloc(pwd); - if (errno == ERANGE) - continue; - if (!noerror) - error("getcwd() failed: %s", strerror(errno)); - return; - } -#else - { - char *p; - int status; - struct job *jp; - int pip[2]; - - pwd = stalloc(MAXPWD); - INTOFF; - if (pipe(pip) < 0) - error("Pipe call failed"); - jp = makejob((union node *)NULL, 1); - if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) { - (void) close(pip[0]); - if (pip[1] != 1) { - close(1); - copyfd(pip[1], 1); - close(pip[1]); - } - (void) execl("/bin/pwd", "pwd", (char *)0); - sh_warn("Cannot exec /bin/pwd"); - exit(1); - } - (void) close(pip[1]); - pip[1] = -1; - p = pwd; - while ((i = read(pip[0], p, pwd + MAXPWD - p)) > 0 - || (i == -1 && errno == EINTR)) { - if (i > 0) - p += i; - } - (void) close(pip[0]); - pip[0] = -1; - status = waitforjob(jp); - if (status != 0) - error((char *)0); - if (i < 0 || p == pwd || p[-1] != '\n') { - if (noerror) { - INTON; - return; - } - error("pwd command failed"); - } - p[-1] = '\0'; - INTON; - curdir = savestr(pwd); - return; - } -#endif -} diff --git a/sh/cd.h b/sh/cd.h deleted file mode 100644 index a4dcc0175e186c9ebcd269ec7031b5016526f62d..0000000000000000000000000000000000000000 --- a/sh/cd.h +++ /dev/null @@ -1,35 +0,0 @@ -/* $NetBSD: cd.h,v 1.4 2003/08/07 09:05:30 agc Exp $ */ - -/*- - * Copyright (c) 1995 - * 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. - * 3. 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. - * - */ - -void getpwd(int); -int cdcmd(int, char **); -int pwdcmd(int, char **); diff --git a/sh/error.c b/sh/error.c deleted file mode 100644 index 8cbed194abe617ec5d757033a9cd4a970d50ca34..0000000000000000000000000000000000000000 --- a/sh/error.c +++ /dev/null @@ -1,366 +0,0 @@ -/* $NetBSD: error.c,v 1.31 2003/08/07 09:05:30 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: error.c,v 1.31 2003/08/07 09:05:30 agc Exp $"); -#endif -#endif /* not lint */ - -/* - * Errors and exceptions. - */ - -#include <signal.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#include "shell.h" -#include "main.h" -#include "options.h" -#include "output.h" -#include "error.h" -#include "show.h" - -#define signal bsd_signal -/* - * Code to handle exceptions in C. - */ - -struct jmploc *handler; -int exception; -volatile int suppressint; -volatile int intpending; -char *commandname; - - -static void exverror(int, const char *, va_list) - __attribute__((__noreturn__)); - -/* - * Called to raise an exception. Since C doesn't include exceptions, we - * just do a longjmp to the exception handler. The type of exception is - * stored in the global variable "exception". - */ - -void -exraise(int e) -{ - if (handler == NULL) - abort(); - exception = e; - longjmp(handler->loc, 1); -} - - -/* - * Called from trap.c when a SIGINT is received. (If the user specifies - * that SIGINT is to be trapped or ignored using the trap builtin, then - * this routine is not called.) Suppressint is nonzero when interrupts - * are held using the INTOFF macro. The call to _exit is necessary because - * there is a short period after a fork before the signal handlers are - * set to the appropriate value for the child. (The test for iflag is - * just defensive programming.) - */ - -void -onint(void) -{ - sigset_t nsigset; - - if (suppressint) { - intpending = 1; - return; - } - intpending = 0; - sigemptyset(&nsigset); - sigprocmask(SIG_SETMASK, &nsigset, NULL); - if (rootshell && iflag) - exraise(EXINT); - else { - signal(SIGINT, SIG_DFL); - raise(SIGINT); - } - /* NOTREACHED */ -} - -static void -exvwarning(int sv_errno, const char *msg, va_list ap) -{ - /* Partially emulate line buffered output so that: - * printf '%d\n' 1 a 2 - * and - * printf '%d %d %d\n' 1 a 2 - * both generate sensible text when stdout and stderr are merged. - */ - if (output.nextc != output.buf && output.nextc[-1] == '\n') - flushout(&output); - if (commandname) - outfmt(&errout, "%s: ", commandname); - if (msg != NULL) { - doformat(&errout, msg, ap); - if (sv_errno >= 0) - outfmt(&errout, ": "); - } - if (sv_errno >= 0) - outfmt(&errout, "%s", strerror(sv_errno)); - out2c('\n'); - flushout(&errout); -} - -/* - * Exverror is called to raise the error exception. If the second argument - * is not NULL then error prints an error message using printf style - * formatting. It then raises the error exception. - */ -static void -exverror(int cond, const char *msg, va_list ap) -{ - CLEAR_PENDING_INT; - INTOFF; - -#ifdef DEBUG - if (msg) { - TRACE(("exverror(%d, \"", cond)); - TRACEV((msg, ap)); - TRACE(("\") pid=%d\n", getpid())); - } else - TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid())); -#endif - if (msg) - exvwarning(-1, msg, ap); - - flushall(); - exraise(cond); - /* NOTREACHED */ -} - - -void -error(const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - exverror(EXERROR, msg, ap); - /* NOTREACHED */ - va_end(ap); -} - - -void -exerror(int cond, const char *msg, ...) -{ - va_list ap; - - va_start(ap, msg); - exverror(cond, msg, ap); - /* NOTREACHED */ - va_end(ap); -} - -/* - * error/warning routines for external builtins - */ - -void -sh_exit(int rval) -{ - exerrno = rval & 255; - exraise(EXEXEC); -} - -void -sh_err(int status, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - exvwarning(errno, fmt, ap); - va_end(ap); - sh_exit(status); -} - -void -sh_verr(int status, const char *fmt, va_list ap) -{ - exvwarning(errno, fmt, ap); - sh_exit(status); -} - -void -sh_errx(int status, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - exvwarning(-1, fmt, ap); - va_end(ap); - sh_exit(status); -} - -void -sh_verrx(int status, const char *fmt, va_list ap) -{ - exvwarning(-1, fmt, ap); - sh_exit(status); -} - -void -sh_warn(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - exvwarning(errno, fmt, ap); - va_end(ap); -} - -void -sh_vwarn(const char *fmt, va_list ap) -{ - exvwarning(errno, fmt, ap); -} - -void -sh_warnx(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - exvwarning(-1, fmt, ap); - va_end(ap); -} - -void -sh_vwarnx(const char *fmt, va_list ap) -{ - exvwarning(-1, fmt, ap); -} - - -/* - * Table of error messages. - */ - -struct errname { - short errcode; /* error number */ - short action; /* operation which encountered the error */ - const char *msg; /* text describing the error */ -}; - - -#define ALL (E_OPEN|E_CREAT|E_EXEC) - -STATIC const struct errname errormsg[] = { - { EINTR, ALL, "interrupted" }, - { EACCES, ALL, "permission denied" }, - { EIO, ALL, "I/O error" }, - { EEXIST, ALL, "file exists" }, - { ENOENT, E_OPEN, "no such file" }, - { ENOENT, E_CREAT,"directory nonexistent" }, - { ENOENT, E_EXEC, "not found" }, - { ENOTDIR, E_OPEN, "no such file" }, - { ENOTDIR, E_CREAT,"directory nonexistent" }, - { ENOTDIR, E_EXEC, "not found" }, - { EISDIR, ALL, "is a directory" }, -#ifdef EMFILE - { EMFILE, ALL, "too many open files" }, -#endif - { ENFILE, ALL, "file table overflow" }, - { ENOSPC, ALL, "file system full" }, -#ifdef EDQUOT - { EDQUOT, ALL, "disk quota exceeded" }, -#endif -#ifdef ENOSR - { ENOSR, ALL, "no streams resources" }, -#endif - { ENXIO, ALL, "no such device or address" }, - { EROFS, ALL, "read-only file system" }, - { ETXTBSY, ALL, "text busy" }, -#ifdef EAGAIN - { EAGAIN, E_EXEC, "not enough memory" }, -#endif - { ENOMEM, ALL, "not enough memory" }, -#ifdef ENOLINK - { ENOLINK, ALL, "remote access failed" }, -#endif -#ifdef EMULTIHOP - { EMULTIHOP, ALL, "remote access failed" }, -#endif -#ifdef ECOMM - { ECOMM, ALL, "remote access failed" }, -#endif -#ifdef ESTALE - { ESTALE, ALL, "remote access failed" }, -#endif -#ifdef ETIMEDOUT - { ETIMEDOUT, ALL, "remote access failed" }, -#endif -#ifdef ELOOP - { ELOOP, ALL, "symbolic link loop" }, -#endif - { E2BIG, E_EXEC, "argument list too long" }, -#ifdef ELIBACC - { ELIBACC, E_EXEC, "shared library missing" }, -#endif - { 0, 0, NULL }, -}; - - -/* - * Return a string describing an error. The returned string may be a - * pointer to a static buffer that will be overwritten on the next call. - * Action describes the operation that got the error. - */ - -const char * -errmsg(int e, int action) -{ - struct errname const *ep; - static char buf[12]; - - for (ep = errormsg ; ep->errcode ; ep++) { - if (ep->errcode == e && (ep->action & action) != 0) - return ep->msg; - } - fmtstr(buf, sizeof buf, "error %d", e); - return buf; -} diff --git a/sh/error.h b/sh/error.h deleted file mode 100644 index 8e70ca4961ba490e358718d4ac563463aa470cd9..0000000000000000000000000000000000000000 --- a/sh/error.h +++ /dev/null @@ -1,117 +0,0 @@ -/* $NetBSD: error.h,v 1.16 2003/08/07 09:05:30 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)error.h 8.2 (Berkeley) 5/4/95 - */ - -#include <stdarg.h> - -/* - * Types of operations (passed to the errmsg routine). - */ - -#define E_OPEN 01 /* opening a file */ -#define E_CREAT 02 /* creating a file */ -#define E_EXEC 04 /* executing a program */ - - -/* - * We enclose jmp_buf in a structure so that we can declare pointers to - * jump locations. The global variable handler contains the location to - * jump to when an exception occurs, and the global variable exception - * contains a code identifying the exeception. To implement nested - * exception handlers, the user should save the value of handler on entry - * to an inner scope, set handler to point to a jmploc structure for the - * inner scope, and restore handler on exit from the scope. - */ - -#include <setjmp.h> - -struct jmploc { - jmp_buf loc; -}; - -extern struct jmploc *handler; -extern int exception; -extern int exerrno; /* error for EXEXEC */ - -/* exceptions */ -#define EXINT 0 /* SIGINT received */ -#define EXERROR 1 /* a generic error */ -#define EXSHELLPROC 2 /* execute a shell procedure */ -#define EXEXEC 3 /* command execution failed */ - - -/* - * These macros allow the user to suspend the handling of interrupt signals - * over a period of time. This is similar to SIGHOLD to or sigblock, but - * much more efficient and portable. (But hacking the kernel is so much - * more fun than worrying about efficiency and portability. :-)) - */ - -extern volatile int suppressint; -extern volatile int intpending; - -#define INTOFF suppressint++ -#define INTON { if (--suppressint == 0 && intpending) onint(); } -#define FORCEINTON {suppressint = 0; if (intpending) onint();} -#define CLEAR_PENDING_INT intpending = 0 -#define int_pending() intpending - -void exraise(int) __attribute__((__noreturn__)); -void onint(void); -void error(const char *, ...) __attribute__((__noreturn__)); -void exerror(int, const char *, ...) __attribute__((__noreturn__)); -const char *errmsg(int, int); - -void sh_err(int, const char *, ...) __attribute__((__noreturn__)); -void sh_verr(int, const char *, va_list) __attribute__((__noreturn__)); -void sh_errx(int, const char *, ...) __attribute__((__noreturn__)); -void sh_verrx(int, const char *, va_list) __attribute__((__noreturn__)); -void sh_warn(const char *, ...); -void sh_vwarn(const char *, va_list); -void sh_warnx(const char *, ...); -void sh_vwarnx(const char *, va_list); - -void sh_exit(int) __attribute__((__noreturn__)); - - -/* - * BSD setjmp saves the signal mask, which violates ANSI C and takes time, - * so we use _setjmp instead. - */ - -#if defined(BSD) && !defined(__SVR4) && !defined(__linux__) -#define setjmp(jmploc) _setjmp(jmploc) -#define longjmp(jmploc, val) _longjmp(jmploc, val) -#endif diff --git a/sh/eval.c b/sh/eval.c deleted file mode 100644 index 9acfd6485dad48837b745e522be2f8b8a81eeedc..0000000000000000000000000000000000000000 --- a/sh/eval.c +++ /dev/null @@ -1,1257 +0,0 @@ -/* $NetBSD: eval.c,v 1.81.2.1 2005/06/13 22:03:51 tron Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; -#else -__RCSID("$NetBSD: eval.c,v 1.81.2.1 2005/06/13 22:03:51 tron Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> -#include <signal.h> -#include <stdio.h> -#include <unistd.h> -#ifdef __linux__ -#include <fcntl.h> -#else -#include <sys/fcntl.h> -#endif -#include <sys/times.h> -#include <sys/param.h> -#include <sys/types.h> -#include <sys/wait.h> - -/* - * Evaluate a command. - */ - -#include "shell.h" -#include "nodes.h" -#include "syntax.h" -#include "expand.h" -#include "parser.h" -#include "jobs.h" -#include "eval.h" -#include "builtins.h" -#include "options.h" -#include "exec.h" -#include "redir.h" -#include "input.h" -#include "output.h" -#include "trap.h" -#include "var.h" -#include "memalloc.h" -#include "error.h" -#include "show.h" -#include "mystring.h" -#include "main.h" -#ifndef SMALL -#include "myhistedit.h" -#endif - - -/* flags in argument to evaltree */ -#define EV_EXIT 01 /* exit after evaluating tree */ -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ -#define EV_BACKCMD 04 /* command executing within back quotes */ - -int evalskip; /* set if we are skipping commands */ -STATIC int skipcount; /* number of levels to skip */ -MKINIT int loopnest; /* current loop nesting level */ -int funcnest; /* depth of function calls */ - - -char *commandname; -struct strlist *cmdenviron; -int exitstatus; /* exit status of last command */ -int back_exitstatus; /* exit status of backquoted command */ - - -STATIC void evalloop(union node *, int); -STATIC void evalfor(union node *, int); -STATIC void evalcase(union node *, int); -STATIC void evalsubshell(union node *, int); -STATIC void expredir(union node *); -STATIC void evalpipe(union node *); -STATIC void evalcommand(union node *, int, struct backcmd *); -STATIC void prehash(union node *); - - -/* - * Called to reset things after an exception. - */ - -#ifdef mkinit -INCLUDE "eval.h" - -RESET { - evalskip = 0; - loopnest = 0; - funcnest = 0; -} - -SHELLPROC { - exitstatus = 0; -} -#endif - -static int -sh_pipe(int fds[2]) -{ - int nfd; - - if (pipe(fds)) - return -1; - - if (fds[0] < 3) { - nfd = fcntl(fds[0], F_DUPFD, 3); - if (nfd != -1) { - close(fds[0]); - fds[0] = nfd; - } - } - - if (fds[1] < 3) { - nfd = fcntl(fds[1], F_DUPFD, 3); - if (nfd != -1) { - close(fds[1]); - fds[1] = nfd; - } - } - return 0; -} - - -/* - * The eval commmand. - */ - -int -evalcmd(int argc, char **argv) -{ - char *p; - char *concat; - char **ap; - - if (argc > 1) { - p = argv[1]; - if (argc > 2) { - STARTSTACKSTR(concat); - ap = argv + 2; - for (;;) { - while (*p) - STPUTC(*p++, concat); - if ((p = *ap++) == NULL) - break; - STPUTC(' ', concat); - } - STPUTC('\0', concat); - p = grabstackstr(concat); - } - evalstring(p, EV_TESTED); - } - return exitstatus; -} - - -/* - * Execute a command or commands contained in a string. - */ - -void -evalstring(char *s, int flag) -{ - union node *n; - struct stackmark smark; - - setstackmark(&smark); - setinputstring(s, 1); - - while ((n = parsecmd(0)) != NEOF) { - evaltree(n, flag); - popstackmark(&smark); - } - popfile(); - popstackmark(&smark); -} - - - -/* - * Evaluate a parse tree. The value is left in the global variable - * exitstatus. - */ - -void -evaltree(union node *n, int flags) -{ - if (n == NULL) { - TRACE(("evaltree(NULL) called\n")); - exitstatus = 0; - goto out; - } -#ifdef WITH_HISTORY - displayhist = 1; /* show history substitutions done with fc */ -#endif - TRACE(("pid %d, evaltree(%p: %d, %d) called\n", - getpid(), n, n->type, flags)); - switch (n->type) { - case NSEMI: - evaltree(n->nbinary.ch1, flags & EV_TESTED); - if (evalskip) - goto out; - evaltree(n->nbinary.ch2, flags); - break; - case NAND: - evaltree(n->nbinary.ch1, EV_TESTED); - if (evalskip || exitstatus != 0) - goto out; - evaltree(n->nbinary.ch2, flags); - break; - case NOR: - evaltree(n->nbinary.ch1, EV_TESTED); - if (evalskip || exitstatus == 0) - goto out; - evaltree(n->nbinary.ch2, flags); - break; - case NREDIR: - expredir(n->nredir.redirect); - redirect(n->nredir.redirect, REDIR_PUSH); - evaltree(n->nredir.n, flags); - popredir(); - break; - case NSUBSHELL: - evalsubshell(n, flags); - break; - case NBACKGND: - evalsubshell(n, flags); - break; - case NIF: { - evaltree(n->nif.test, EV_TESTED); - if (evalskip) - goto out; - if (exitstatus == 0) - evaltree(n->nif.ifpart, flags); - else if (n->nif.elsepart) - evaltree(n->nif.elsepart, flags); - else - exitstatus = 0; - break; - } - case NWHILE: - case NUNTIL: - evalloop(n, flags); - break; - case NFOR: - evalfor(n, flags); - break; - case NCASE: - evalcase(n, flags); - break; - case NDEFUN: - defun(n->narg.text, n->narg.next); - exitstatus = 0; - break; - case NNOT: - evaltree(n->nnot.com, EV_TESTED); - exitstatus = !exitstatus; - break; - case NPIPE: - evalpipe(n); - break; - case NCMD: - evalcommand(n, flags, (struct backcmd *)NULL); - break; - default: - out1fmt("Node type = %d\n", n->type); - flushout(&output); - break; - } -out: - if (pendingsigs) - dotrap(); - if ((flags & EV_EXIT) != 0) - exitshell(exitstatus); -} - - -STATIC void -evalloop(union node *n, int flags) -{ - int status; - - loopnest++; - status = 0; - for (;;) { - evaltree(n->nbinary.ch1, EV_TESTED); - if (evalskip) { -skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { - evalskip = 0; - continue; - } - if (evalskip == SKIPBREAK && --skipcount <= 0) - evalskip = 0; - break; - } - if (n->type == NWHILE) { - if (exitstatus != 0) - break; - } else { - if (exitstatus == 0) - break; - } - evaltree(n->nbinary.ch2, flags & EV_TESTED); - status = exitstatus; - if (evalskip) - goto skipping; - } - loopnest--; - exitstatus = status; -} - - - -STATIC void -evalfor(union node *n, int flags) -{ - struct arglist arglist; - union node *argp; - struct strlist *sp; - struct stackmark smark; - int status = 0; - - setstackmark(&smark); - arglist.lastp = &arglist.list; - for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { - expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); - if (evalskip) - goto out; - } - *arglist.lastp = NULL; - - loopnest++; - for (sp = arglist.list ; sp ; sp = sp->next) { - setvar(n->nfor.var, sp->text, 0); - evaltree(n->nfor.body, flags & EV_TESTED); - status = exitstatus; - if (evalskip) { - if (evalskip == SKIPCONT && --skipcount <= 0) { - evalskip = 0; - continue; - } - if (evalskip == SKIPBREAK && --skipcount <= 0) - evalskip = 0; - break; - } - } - loopnest--; - exitstatus = status; -out: - popstackmark(&smark); -} - - - -STATIC void -evalcase(union node *n, int flags) -{ - union node *cp; - union node *patp; - struct arglist arglist; - struct stackmark smark; - int status = 0; - - setstackmark(&smark); - arglist.lastp = &arglist.list; - expandarg(n->ncase.expr, &arglist, EXP_TILDE); - for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { - for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { - if (casematch(patp, arglist.list->text)) { - if (evalskip == 0) { - evaltree(cp->nclist.body, flags); - status = exitstatus; - } - goto out; - } - } - } -out: - exitstatus = status; - popstackmark(&smark); -} - - - -/* - * Kick off a subshell to evaluate a tree. - */ - -STATIC void -evalsubshell(union node *n, int flags) -{ - struct job *jp; - int backgnd = (n->type == NBACKGND); - - expredir(n->nredir.redirect); - INTOFF; - jp = makejob(n, 1); - if (forkshell(jp, n, backgnd) == 0) { - INTON; - if (backgnd) - flags &=~ EV_TESTED; - redirect(n->nredir.redirect, 0); - /* never returns */ - evaltree(n->nredir.n, flags | EV_EXIT); - } - if (! backgnd) - exitstatus = waitforjob(jp); - INTON; -} - - - -/* - * Compute the names of the files in a redirection list. - */ - -STATIC void -expredir(union node *n) -{ - union node *redir; - - for (redir = n ; redir ; redir = redir->nfile.next) { - struct arglist fn; - fn.lastp = &fn.list; - switch (redir->type) { - case NFROMTO: - case NFROM: - case NTO: - case NCLOBBER: - case NAPPEND: - expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); - redir->nfile.expfname = fn.list->text; - break; - case NFROMFD: - case NTOFD: - if (redir->ndup.vname) { - expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); - fixredir(redir, fn.list->text, 1); - } - break; - } - } -} - - - -/* - * Evaluate a pipeline. All the processes in the pipeline are children - * of the process creating the pipeline. (This differs from some versions - * of the shell, which make the last process in a pipeline the parent - * of all the rest.) - */ - -STATIC void -evalpipe(union node *n) -{ - struct job *jp; - struct nodelist *lp; - int pipelen; - int prevfd; - int pip[2]; - - TRACE(("evalpipe(0x%lx) called\n", (long)n)); - pipelen = 0; - for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) - pipelen++; - INTOFF; - jp = makejob(n, pipelen); - prevfd = -1; - for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { - prehash(lp->n); - pip[1] = -1; - if (lp->next) { - if (sh_pipe(pip) < 0) { - close(prevfd); - error("Pipe call failed"); - } - } - if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { - INTON; - if (prevfd > 0) { - close(0); - copyfd(prevfd, 0); - close(prevfd); - } - if (pip[1] >= 0) { - close(pip[0]); - if (pip[1] != 1) { - close(1); - copyfd(pip[1], 1); - close(pip[1]); - } - } - evaltree(lp->n, EV_EXIT); - } - if (prevfd >= 0) - close(prevfd); - prevfd = pip[0]; - close(pip[1]); - } - if (n->npipe.backgnd == 0) { - exitstatus = waitforjob(jp); - TRACE(("evalpipe: job done exit status %d\n", exitstatus)); - } - INTON; -} - - - -/* - * Execute a command inside back quotes. If it's a builtin command, we - * want to save its output in a block obtained from malloc. Otherwise - * we fork off a subprocess and get the output of the command via a pipe. - * Should be called with interrupts off. - */ - -void -evalbackcmd(union node *n, struct backcmd *result) -{ - int pip[2]; - struct job *jp; - struct stackmark smark; /* unnecessary */ - - setstackmark(&smark); - result->fd = -1; - result->buf = NULL; - result->nleft = 0; - result->jp = NULL; - if (n == NULL) { - goto out; - } -#ifdef notyet - /* - * For now we disable executing builtins in the same - * context as the shell, because we are not keeping - * enough state to recover from changes that are - * supposed only to affect subshells. eg. echo "`cd /`" - */ - if (n->type == NCMD) { - exitstatus = oexitstatus; - evalcommand(n, EV_BACKCMD, result); - } else -#endif - { - INTOFF; - if (sh_pipe(pip) < 0) - error("Pipe call failed"); - jp = makejob(n, 1); - if (forkshell(jp, n, FORK_NOJOB) == 0) { - FORCEINTON; - close(pip[0]); - if (pip[1] != 1) { - close(1); - copyfd(pip[1], 1); - close(pip[1]); - } - eflag = 0; - evaltree(n, EV_EXIT); - /* NOTREACHED */ - } - close(pip[1]); - result->fd = pip[0]; - result->jp = jp; - INTON; - } -out: - popstackmark(&smark); - TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", - result->fd, result->buf, result->nleft, result->jp)); -} - -static const char * -syspath(void) -{ - static char *sys_path = NULL; -#ifndef __linux__ - static int mib[] = {CTL_USER, USER_CS_PATH}; -#endif - static char def_path[] = "PATH=/usr/bin:/bin:/usr/sbin:/sbin"; - - if (sys_path == NULL) { -#ifndef __linux__ - size_t len; - if (sysctl(mib, 2, 0, &len, 0, 0) != -1 && - (sys_path = ckmalloc(len + 5)) != NULL && - sysctl(mib, 2, sys_path + 5, &len, 0, 0) != -1) { - memcpy(sys_path, "PATH=", 5); - } else -#endif - { - ckfree(sys_path); - /* something to keep things happy */ - sys_path = def_path; - } - } - return sys_path; -} - -static int -parse_command_args(int argc, char **argv, int *use_syspath) -{ - int sv_argc = argc; - char *cp, c; - - *use_syspath = 0; - - for (;;) { - argv++; - if (--argc == 0) - break; - cp = *argv; - if (*cp++ != '-') - break; - if (*cp == '-' && cp[1] == 0) { - argv++; - argc--; - break; - } - while ((c = *cp++)) { - switch (c) { - case 'p': - *use_syspath = 1; - break; - default: - /* run 'typecmd' for other options */ - return 0; - } - } - } - return sv_argc - argc; -} - -int vforked = 0; - -/* - * Execute a simple command. - */ - -STATIC void -evalcommand(union node *cmd, int flags, struct backcmd *backcmd) -{ - struct stackmark smark; - union node *argp; - struct arglist arglist; - struct arglist varlist; - char **argv; - int argc; - char **envp; - int varflag; - struct strlist *sp; - int mode; - int pip[2]; - struct cmdentry cmdentry; - struct job *jp; - struct jmploc jmploc; - struct jmploc *volatile savehandler; - char *volatile savecmdname; - volatile struct shparam saveparam; - struct localvar *volatile savelocalvars; - volatile int e; - char *lastarg; - const char *path = pathval(); - volatile int temp_path; -#if __GNUC__ - /* Avoid longjmp clobbering */ - (void) &argv; - (void) &argc; - (void) &lastarg; - (void) &flags; -#endif - - vforked = 0; - /* First expand the arguments. */ - TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); - setstackmark(&smark); - back_exitstatus = 0; - - arglist.lastp = &arglist.list; - varflag = 1; - /* Expand arguments, ignoring the initial 'name=value' ones */ - for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { - char *p = argp->narg.text; - if (varflag && is_name(*p)) { - do { - p++; - } while (is_in_name(*p)); - if (*p == '=') - continue; - } - expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); - varflag = 0; - } - *arglist.lastp = NULL; - - expredir(cmd->ncmd.redirect); - - /* Now do the initial 'name=value' ones we skipped above */ - varlist.lastp = &varlist.list; - for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { - char *p = argp->narg.text; - if (!is_name(*p)) - break; - do - p++; - while (is_in_name(*p)); - if (*p != '=') - break; - expandarg(argp, &varlist, EXP_VARTILDE); - } - *varlist.lastp = NULL; - - argc = 0; - for (sp = arglist.list ; sp ; sp = sp->next) - argc++; - argv = stalloc(sizeof (char *) * (argc + 1)); - - for (sp = arglist.list ; sp ; sp = sp->next) { - TRACE(("evalcommand arg: %s\n", sp->text)); - *argv++ = sp->text; - } - *argv = NULL; - lastarg = NULL; - if (iflag && funcnest == 0 && argc > 0) - lastarg = argv[-1]; - argv -= argc; - - /* Print the command if xflag is set. */ - if (xflag) { - char sep = 0; - out2str(ps4val()); - for (sp = varlist.list ; sp ; sp = sp->next) { - if (sep != 0) - outc(sep, &errout); - out2str(sp->text); - sep = ' '; - } - for (sp = arglist.list ; sp ; sp = sp->next) { - if (sep != 0) - outc(sep, &errout); - out2str(sp->text); - sep = ' '; - } - outc('\n', &errout); - flushout(&errout); - } - - /* Now locate the command. */ - if (argc == 0) { - cmdentry.cmdtype = CMDSPLBLTIN; - cmdentry.u.bltin = bltincmd; - } else { - static const char PATH[] = "PATH="; - int cmd_flags = DO_ERR; - - /* - * Modify the command lookup path, if a PATH= assignment - * is present - */ - for (sp = varlist.list; sp; sp = sp->next) - if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) - path = sp->text + sizeof(PATH) - 1; - - do { - int argsused, use_syspath; - find_command(argv[0], &cmdentry, cmd_flags, path); - if (cmdentry.cmdtype == CMDUNKNOWN) { - exitstatus = 127; - flushout(&errout); - goto out; - } - - /* implement the 'command' builtin here */ - if (cmdentry.cmdtype != CMDBUILTIN || - cmdentry.u.bltin != bltincmd) - break; - cmd_flags |= DO_NOFUNC; - argsused = parse_command_args(argc, argv, &use_syspath); - if (argsused == 0) { - /* use 'type' builting to display info */ - cmdentry.u.bltin = typecmd; - break; - } - argc -= argsused; - argv += argsused; - if (use_syspath) - path = syspath() + 5; - } while (argc != 0); - if (cmdentry.cmdtype == CMDSPLBLTIN && cmd_flags & DO_NOFUNC) - /* posix mandates that 'command <splbltin>' act as if - <splbltin> was a normal builtin */ - cmdentry.cmdtype = CMDBUILTIN; - } - - /* Fork off a child process if necessary. */ - if (cmd->ncmd.backgnd - || (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) - || ((flags & EV_BACKCMD) != 0 - && ((cmdentry.cmdtype != CMDBUILTIN && cmdentry.cmdtype != CMDSPLBLTIN) - || cmdentry.u.bltin == dotcmd - || cmdentry.u.bltin == evalcmd))) { - INTOFF; - jp = makejob(cmd, 1); - mode = cmd->ncmd.backgnd; - if (flags & EV_BACKCMD) { - mode = FORK_NOJOB; - if (sh_pipe(pip) < 0) - error("Pipe call failed"); - } -#ifdef DO_SHAREDVFORK - /* It is essential that if DO_SHAREDVFORK is defined that the - * child's address space is actually shared with the parent as - * we rely on this. - */ - if (cmdentry.cmdtype == CMDNORMAL) { - pid_t pid; - - savelocalvars = localvars; - localvars = NULL; - vforked = 1; - switch (pid = vfork()) { - case -1: - TRACE(("Vfork failed, errno=%d\n", errno)); - INTON; - error("Cannot vfork"); - break; - case 0: - /* Make sure that exceptions only unwind to - * after the vfork(2) - */ - if (setjmp(jmploc.loc)) { - if (exception == EXSHELLPROC) { - /* We can't progress with the vfork, - * so, set vforked = 2 so the parent - * knows, and _exit(); - */ - vforked = 2; - _exit(0); - } else { - _exit(exerrno); - } - } - savehandler = handler; - handler = &jmploc; - listmklocal(varlist.list, VEXPORT | VNOFUNC); - forkchild(jp, cmd, mode, vforked); - break; - default: - handler = savehandler; /* restore from vfork(2) */ - poplocalvars(); - localvars = savelocalvars; - if (vforked == 2) { - vforked = 0; - - (void)waitpid(pid, NULL, 0); - /* We need to progress in a normal fork fashion */ - goto normal_fork; - } - vforked = 0; - forkparent(jp, cmd, mode, pid); - goto parent; - } - } else { -normal_fork: -#endif - if (forkshell(jp, cmd, mode) != 0) - goto parent; /* at end of routine */ - FORCEINTON; -#ifdef DO_SHAREDVFORK - } -#endif - if (flags & EV_BACKCMD) { - if (!vforked) { - FORCEINTON; - } - close(pip[0]); - if (pip[1] != 1) { - close(1); - copyfd(pip[1], 1); - close(pip[1]); - } - } - flags |= EV_EXIT; - } - - /* This is the child process if a fork occurred. */ - /* Execute the command. */ - switch (cmdentry.cmdtype) { - case CMDFUNCTION: -#ifdef DEBUG - trputs("Shell function: "); trargs(argv); -#endif - redirect(cmd->ncmd.redirect, REDIR_PUSH); - saveparam = shellparam; - shellparam.malloc = 0; - shellparam.reset = 1; - shellparam.nparam = argc - 1; - shellparam.p = argv + 1; - shellparam.optnext = NULL; - INTOFF; - savelocalvars = localvars; - localvars = NULL; - INTON; - if (setjmp(jmploc.loc)) { - if (exception == EXSHELLPROC) { - freeparam((volatile struct shparam *) - &saveparam); - } else { - freeparam(&shellparam); - shellparam = saveparam; - } - poplocalvars(); - localvars = savelocalvars; - handler = savehandler; - longjmp(handler->loc, 1); - } - savehandler = handler; - handler = &jmploc; - listmklocal(varlist.list, 0); - /* stop shell blowing its stack */ - if (++funcnest > 1000) - error("too many nested function calls"); - evaltree(cmdentry.u.func, flags & EV_TESTED); - funcnest--; - INTOFF; - poplocalvars(); - localvars = savelocalvars; - freeparam(&shellparam); - shellparam = saveparam; - handler = savehandler; - popredir(); - INTON; - if (evalskip == SKIPFUNC) { - evalskip = 0; - skipcount = 0; - } - if (flags & EV_EXIT) - exitshell(exitstatus); - break; - - case CMDBUILTIN: - case CMDSPLBLTIN: -#ifdef DEBUG - trputs("builtin command: "); trargs(argv); -#endif - mode = (cmdentry.u.bltin == execcmd) ? 0 : REDIR_PUSH; - if (flags == EV_BACKCMD) { - memout.nleft = 0; - memout.nextc = memout.buf; - memout.bufsize = 64; - mode |= REDIR_BACKQ; - } - e = -1; - savehandler = handler; - savecmdname = commandname; - handler = &jmploc; - if (!setjmp(jmploc.loc)) { - /* We need to ensure the command hash table isn't - * corruped by temporary PATH assignments. - * However we must ensure the 'local' command works! - */ - if (path != pathval() && (cmdentry.u.bltin == hashcmd || - cmdentry.u.bltin == typecmd)) { - savelocalvars = localvars; - localvars = 0; - mklocal(path - 5 /* PATH= */, 0); - temp_path = 1; - } else - temp_path = 0; - redirect(cmd->ncmd.redirect, mode); - - /* exec is a special builtin, but needs this list... */ - cmdenviron = varlist.list; - /* we must check 'readonly' flag for all builtins */ - listsetvar(varlist.list, - cmdentry.cmdtype == CMDSPLBLTIN ? 0 : VNOSET); - commandname = argv[0]; - /* initialize nextopt */ - argptr = argv + 1; - optptr = NULL; - /* and getopt */ -#ifndef __linux__ - optreset = 1; -#endif - optind = 1; - exitstatus = cmdentry.u.bltin(argc, argv); - } else { - e = exception; - exitstatus = e == EXINT ? SIGINT + 128 : - e == EXEXEC ? exerrno : 2; - } - handler = savehandler; - flushall(); - out1 = &output; - out2 = &errout; - freestdout(); - if (temp_path) { - poplocalvars(); - localvars = savelocalvars; - } - cmdenviron = NULL; - if (e != EXSHELLPROC) { - commandname = savecmdname; - if (flags & EV_EXIT) - exitshell(exitstatus); - } - if (e != -1) { - if ((e != EXERROR && e != EXEXEC) - || cmdentry.cmdtype == CMDSPLBLTIN) - exraise(e); - FORCEINTON; - } - if (cmdentry.u.bltin != execcmd) - popredir(); - if (flags == EV_BACKCMD) { - backcmd->buf = memout.buf; - backcmd->nleft = memout.nextc - memout.buf; - memout.buf = NULL; - } - break; - - default: -#ifdef DEBUG - trputs("normal command: "); trargs(argv); -#endif - clearredir(vforked); - redirect(cmd->ncmd.redirect, vforked ? REDIR_VFORK : 0); - if (!vforked) - for (sp = varlist.list ; sp ; sp = sp->next) - setvareq(sp->text, VEXPORT|VSTACK); - envp = environment(); - shellexec(argv, envp, path, cmdentry.u.index, vforked); - break; - } - goto out; - -parent: /* parent process gets here (if we forked) */ - if (mode == FORK_FG) { /* argument to fork */ - exitstatus = waitforjob(jp); - } else if (mode == FORK_NOJOB) { - backcmd->fd = pip[0]; - close(pip[1]); - backcmd->jp = jp; - } - FORCEINTON; - -out: - if (lastarg) - /* dsl: I think this is intended to be used to support - * '_' in 'vi' command mode during line editing... - * However I implemented that within libedit itself. - */ - setvar("_", lastarg, 0); - popstackmark(&smark); - - if (eflag && exitstatus && !(flags & EV_TESTED)) - exitshell(exitstatus); -} - - -/* - * Search for a command. This is called before we fork so that the - * location of the command will be available in the parent as well as - * the child. The check for "goodname" is an overly conservative - * check that the name will not be subject to expansion. - */ - -STATIC void -prehash(union node *n) -{ - struct cmdentry entry; - - if (n->type == NCMD && n->ncmd.args) - if (goodname(n->ncmd.args->narg.text)) - find_command(n->ncmd.args->narg.text, &entry, 0, - pathval()); -} - - - -/* - * Builtin commands. Builtin commands whose functions are closely - * tied to evaluation are implemented here. - */ - -/* - * No command given. - */ - -int -bltincmd(int argc, char **argv) -{ - /* - * Preserve exitstatus of a previous possible redirection - * as POSIX mandates - */ - return back_exitstatus; -} - - -/* - * Handle break and continue commands. Break, continue, and return are - * all handled by setting the evalskip flag. The evaluation routines - * above all check this flag, and if it is set they start skipping - * commands rather than executing them. The variable skipcount is - * the number of loops to break/continue, or the number of function - * levels to return. (The latter is always 1.) It should probably - * be an error to break out of more loops than exist, but it isn't - * in the standard shell so we don't make it one here. - */ - -int -breakcmd(int argc, char **argv) -{ - int n = argc > 1 ? number(argv[1]) : 1; - - if (n > loopnest) - n = loopnest; - if (n > 0) { - evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK; - skipcount = n; - } - return 0; -} - - -/* - * The return command. - */ - -int -returncmd(int argc, char **argv) -{ - int ret = argc > 1 ? number(argv[1]) : exitstatus; - - if (funcnest) { - evalskip = SKIPFUNC; - skipcount = 1; - return ret; - } - else { - /* Do what ksh does; skip the rest of the file */ - evalskip = SKIPFILE; - skipcount = 1; - return ret; - } -} - - -int -falsecmd(int argc, char **argv) -{ - return 1; -} - - -int -truecmd(int argc, char **argv) -{ - return 0; -} - - -int -execcmd(int argc, char **argv) -{ - if (argc > 1) { - struct strlist *sp; - - iflag = 0; /* exit on error */ - mflag = 0; - optschanged(); - for (sp = cmdenviron; sp; sp = sp->next) - setvareq(sp->text, VEXPORT|VSTACK); - shellexec(argv + 1, environment(), pathval(), 0, 0); - } - return 0; -} - -static int -conv_time(clock_t ticks, char *seconds, size_t l) -{ - static clock_t tpm = 0; - clock_t mins; - int i; - - mins = ticks / tpm; - snprintf(seconds, l, "%.4f", (ticks - mins * tpm) * 60.0 / tpm ); - - if (seconds[0] == '6' && seconds[1] == '0') { - /* 59.99995 got rounded up... */ - mins++; - strlcpy(seconds, "0.0", l); - return mins; - } - - /* suppress trailing zeros */ - i = strlen(seconds) - 1; - for (; seconds[i] == '0' && seconds[i - 1] != '.'; i--) - seconds[i] = 0; - return mins; -} - -int -timescmd(int argc, char **argv) -{ - struct tms tms; - int u, s, cu, cs; - char us[8], ss[8], cus[8], css[8]; - - nextopt(""); - - times(&tms); - - u = conv_time(tms.tms_utime, us, sizeof(us)); - s = conv_time(tms.tms_stime, ss, sizeof(ss)); - cu = conv_time(tms.tms_cutime, cus, sizeof(cus)); - cs = conv_time(tms.tms_cstime, css, sizeof(css)); - - outfmt(out1, "%dm%ss %dm%ss\n%dm%ss %dm%ss\n", - u, us, s, ss, cu, cus, cs, css); - - return 0; -} diff --git a/sh/eval.h b/sh/eval.h deleted file mode 100644 index 155bc4441c5dcdfb8bfff40b4ff161e5bb994c81..0000000000000000000000000000000000000000 --- a/sh/eval.h +++ /dev/null @@ -1,64 +0,0 @@ -/* $NetBSD: eval.h,v 1.14 2003/08/07 09:05:31 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)eval.h 8.2 (Berkeley) 5/4/95 - */ - -extern char *commandname; /* currently executing command */ -extern int exitstatus; /* exit status of last command */ -extern int back_exitstatus; /* exit status of backquoted command */ -extern struct strlist *cmdenviron; /* environment for builtin command */ - - -struct backcmd { /* result of evalbackcmd */ - int fd; /* file descriptor to read from */ - char *buf; /* buffer */ - int nleft; /* number of chars in buffer */ - struct job *jp; /* job structure for command */ -}; - -void evalstring(char *, int); -union node; /* BLETCH for ansi C */ -void evaltree(union node *, int); -void evalbackcmd(union node *, struct backcmd *); - -/* in_function returns nonzero if we are currently evaluating a function */ -#define in_function() funcnest -extern int funcnest; -extern int evalskip; - -/* reasons for skipping commands (see comment on breakcmd routine) */ -#define SKIPBREAK 1 -#define SKIPCONT 2 -#define SKIPFUNC 3 -#define SKIPFILE 4 diff --git a/sh/exec.c b/sh/exec.c deleted file mode 100644 index fe3613fa9239ae7648a4ef23015fc272621f9717..0000000000000000000000000000000000000000 --- a/sh/exec.c +++ /dev/null @@ -1,1063 +0,0 @@ -/* $NetBSD: exec.c,v 1.37 2003/08/07 09:05:31 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95"; -#else -__RCSID("$NetBSD: exec.c,v 1.37 2003/08/07 09:05:31 agc Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/wait.h> -#include <unistd.h> -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> - -/* - * When commands are first encountered, they are entered in a hash table. - * This ensures that a full path search will not have to be done for them - * on each invocation. - * - * We should investigate converting to a linear search, even though that - * would make the command name "hash" a misnomer. - */ - -#include "shell.h" -#include "main.h" -#include "nodes.h" -#include "parser.h" -#include "redir.h" -#include "eval.h" -#include "exec.h" -#include "builtins.h" -#include "var.h" -#include "options.h" -#include "input.h" -#include "output.h" -#include "syntax.h" -#include "memalloc.h" -#include "error.h" -#include "init.h" -#include "mystring.h" -#include "show.h" -#include "jobs.h" -#include "alias.h" - - -#define CMDTABLESIZE 31 /* should be prime */ -#define ARB 1 /* actual size determined at run time */ - - - -struct tblentry { - struct tblentry *next; /* next entry in hash chain */ - union param param; /* definition of builtin function */ - short cmdtype; /* index identifying command */ - char rehash; /* if set, cd done since entry created */ - char cmdname[ARB]; /* name of command */ -}; - - -STATIC struct tblentry *cmdtable[CMDTABLESIZE]; -STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */ -int exerrno = 0; /* Last exec error */ - - -STATIC void tryexec(char *, char **, char **, int); -STATIC void execinterp(char **, char **); -STATIC void printentry(struct tblentry *, int); -STATIC void clearcmdentry(int); -STATIC struct tblentry *cmdlookup(const char *, int); -STATIC void delete_cmd_entry(void); - - -extern char *const parsekwd[]; - -/* - * Exec a program. Never returns. If you change this routine, you may - * have to change the find_command routine as well. - */ - -void -shellexec(char **argv, char **envp, const char *path, int idx, int vforked) -{ - char *cmdname; - int e; - - if (strchr(argv[0], '/') != NULL) { - tryexec(argv[0], argv, envp, vforked); - e = errno; - } else { - e = ENOENT; - while ((cmdname = padvance(&path, argv[0])) != NULL) { - if (--idx < 0 && pathopt == NULL) { - tryexec(cmdname, argv, envp, vforked); - if (errno != ENOENT && errno != ENOTDIR) - e = errno; - } - stunalloc(cmdname); - } - } - - /* Map to POSIX errors */ - switch (e) { - case EACCES: - exerrno = 126; - break; - case ENOENT: - exerrno = 127; - break; - default: - exerrno = 2; - break; - } - TRACE(("shellexec failed for %s, errno %d, vforked %d, suppressint %d\n", - argv[0], e, vforked, suppressint )); - exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC)); - /* NOTREACHED */ -} - - -STATIC void -tryexec(char *cmd, char **argv, char **envp, int vforked) -{ - int e; -#ifndef BSD - char *p; -#endif - -#ifdef SYSV - do { - execve(cmd, argv, envp); - } while (errno == EINTR); -#else - execve(cmd, argv, envp); -#endif - e = errno; - if (e == ENOEXEC) { - if (vforked) { - /* We are currently vfork(2)ed, so raise an - * exception, and evalcommand will try again - * with a normal fork(2). - */ - exraise(EXSHELLPROC); - } - initshellproc(); - setinputfile(cmd, 0); - commandname = arg0 = savestr(argv[0]); -#if !defined(BSD) && !defined(__linux__) - pgetc(); pungetc(); /* fill up input buffer */ - p = parsenextc; - if (parsenleft > 2 && p[0] == '#' && p[1] == '!') { - argv[0] = cmd; - execinterp(argv, envp); - } -#endif - setparam(argv + 1); - exraise(EXSHELLPROC); - } - errno = e; -} - - -#if !defined(BSD) && !defined(__linux__) -/* - * Execute an interpreter introduced by "#!", for systems where this - * feature has not been built into the kernel. If the interpreter is - * the shell, return (effectively ignoring the "#!"). If the execution - * of the interpreter fails, exit. - * - * This code peeks inside the input buffer in order to avoid actually - * reading any input. It would benefit from a rewrite. - */ - -#define NEWARGS 5 - -STATIC void -execinterp(char **argv, char **envp) -{ - int n; - char *inp; - char *outp; - char c; - char *p; - char **ap; - char *newargs[NEWARGS]; - int i; - char **ap2; - char **new; - - n = parsenleft - 2; - inp = parsenextc + 2; - ap = newargs; - for (;;) { - while (--n >= 0 && (*inp == ' ' || *inp == '\t')) - inp++; - if (n < 0) - goto bad; - if ((c = *inp++) == '\n') - break; - if (ap == &newargs[NEWARGS]) -bad: error("Bad #! line"); - STARTSTACKSTR(outp); - do { - STPUTC(c, outp); - } while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n'); - STPUTC('\0', outp); - n++, inp--; - *ap++ = grabstackstr(outp); - } - if (ap == newargs + 1) { /* if no args, maybe no exec is needed */ - p = newargs[0]; - for (;;) { - if (equal(p, "sh") || equal(p, "ash")) { - return; - } - while (*p != '/') { - if (*p == '\0') - goto break2; - p++; - } - p++; - } -break2:; - } - i = (char *)ap - (char *)newargs; /* size in bytes */ - if (i == 0) - error("Bad #! line"); - for (ap2 = argv ; *ap2++ != NULL ; ); - new = ckmalloc(i + ((char *)ap2 - (char *)argv)); - ap = newargs, ap2 = new; - while ((i -= sizeof (char **)) >= 0) - *ap2++ = *ap++; - ap = argv; - while (*ap2++ = *ap++); - shellexec(new, envp, pathval(), 0); - /* NOTREACHED */ -} -#endif - - - -/* - * Do a path search. The variable path (passed by reference) should be - * set to the start of the path before the first call; padvance will update - * this value as it proceeds. Successive calls to padvance will return - * the possible path expansions in sequence. If an option (indicated by - * a percent sign) appears in the path entry then the global variable - * pathopt will be set to point to it; otherwise pathopt will be set to - * NULL. - */ - -const char *pathopt; - -char * -padvance(const char **path, const char *name) -{ - const char *p; - char *q; - const char *start; - int len; - - if (*path == NULL) - return NULL; - start = *path; - for (p = start ; *p && *p != ':' && *p != '%' ; p++); - len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ - while (stackblocksize() < len) - growstackblock(); - q = stackblock(); - if (p != start) { - memcpy(q, start, p - start); - q += p - start; - *q++ = '/'; - } - strcpy(q, name); - pathopt = NULL; - if (*p == '%') { - pathopt = ++p; - while (*p && *p != ':') p++; - } - if (*p == ':') - *path = p + 1; - else - *path = NULL; - return stalloc(len); -} - - - -/*** Command hashing code ***/ - - -int -hashcmd(int argc, char **argv) -{ - struct tblentry **pp; - struct tblentry *cmdp; - int c; - int verbose; - struct cmdentry entry; - char *name; - - verbose = 0; - while ((c = nextopt("rv")) != '\0') { - if (c == 'r') { - clearcmdentry(0); - } else if (c == 'v') { - verbose++; - } - } - if (*argptr == NULL) { - for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { - for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { - if (verbose || cmdp->cmdtype == CMDNORMAL) - printentry(cmdp, verbose); - } - } - return 0; - } - while ((name = *argptr) != NULL) { - if ((cmdp = cmdlookup(name, 0)) != NULL - && (cmdp->cmdtype == CMDNORMAL - || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) - delete_cmd_entry(); - find_command(name, &entry, DO_ERR, pathval()); - if (verbose) { - if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */ - cmdp = cmdlookup(name, 0); - printentry(cmdp, verbose); - } - flushall(); - } - argptr++; - } - return 0; -} - - -STATIC void -printentry(struct tblentry *cmdp, int verbose) -{ - int idx; - const char *path; - char *name; - - switch (cmdp->cmdtype) { - case CMDNORMAL: - idx = cmdp->param.index; - path = pathval(); - do { - name = padvance(&path, cmdp->cmdname); - stunalloc(name); - } while (--idx >= 0); - out1str(name); - break; - case CMDSPLBLTIN: - out1fmt("special builtin %s", cmdp->cmdname); - break; - case CMDBUILTIN: - out1fmt("builtin %s", cmdp->cmdname); - break; - case CMDFUNCTION: - out1fmt("function %s", cmdp->cmdname); - if (verbose) { - struct procstat ps; - INTOFF; - commandtext(&ps, cmdp->param.func); - INTON; - out1str("() { "); - out1str(ps.cmd); - out1str("; }"); - } - break; - default: - error("internal error: %s cmdtype %d", cmdp->cmdname, cmdp->cmdtype); - } - if (cmdp->rehash) - out1c('*'); - out1c('\n'); -} - - - -/* - * Resolve a command name. If you change this routine, you may have to - * change the shellexec routine as well. - */ - -void -find_command(char *name, struct cmdentry *entry, int act, const char *path) -{ - struct tblentry *cmdp, loc_cmd; - int idx; - int prev; - char *fullname; - struct stat statb; - int e; - int (*bltin)(int,char **); - - /* If name contains a slash, don't use PATH or hash table */ - if (strchr(name, '/') != NULL) { - if (act & DO_ABS) { - while (stat(name, &statb) < 0) { -#ifdef SYSV - if (errno == EINTR) - continue; -#endif - if (errno != ENOENT && errno != ENOTDIR) - e = errno; - entry->cmdtype = CMDUNKNOWN; - entry->u.index = -1; - return; - } - entry->cmdtype = CMDNORMAL; - entry->u.index = -1; - return; - } - entry->cmdtype = CMDNORMAL; - entry->u.index = 0; - return; - } - - if (path != pathval()) - act |= DO_ALTPATH; - - if (act & DO_ALTPATH && strstr(path, "%builtin") != NULL) - act |= DO_ALTBLTIN; - - /* If name is in the table, check answer will be ok */ - if ((cmdp = cmdlookup(name, 0)) != NULL) { - do { - switch (cmdp->cmdtype) { - case CMDNORMAL: - if (act & DO_ALTPATH) { - cmdp = NULL; - continue; - } - break; - case CMDFUNCTION: - if (act & DO_NOFUNC) { - cmdp = NULL; - continue; - } - break; - case CMDBUILTIN: - if ((act & DO_ALTBLTIN) || builtinloc >= 0) { - cmdp = NULL; - continue; - } - break; - } - /* if not invalidated by cd, we're done */ - if (cmdp->rehash == 0) - goto success; - } while (0); - } - - /* If %builtin not in path, check for builtin next */ - if ((act & DO_ALTPATH ? !(act & DO_ALTBLTIN) : builtinloc < 0) && - (bltin = find_builtin(name)) != 0) - goto builtin_success; - - /* We have to search path. */ - prev = -1; /* where to start */ - if (cmdp) { /* doing a rehash */ - if (cmdp->cmdtype == CMDBUILTIN) - prev = builtinloc; - else - prev = cmdp->param.index; - } - - e = ENOENT; - idx = -1; -loop: - while ((fullname = padvance(&path, name)) != NULL) { - stunalloc(fullname); - idx++; - if (pathopt) { - if (prefix("builtin", pathopt)) { - if ((bltin = find_builtin(name)) == 0) - goto loop; - goto builtin_success; - } else if (prefix("func", pathopt)) { - /* handled below */ - } else { - /* ignore unimplemented options */ - goto loop; - } - } - /* if rehash, don't redo absolute path names */ - if (fullname[0] == '/' && idx <= prev) { - if (idx < prev) - goto loop; - TRACE(("searchexec \"%s\": no change\n", name)); - goto success; - } - while (stat(fullname, &statb) < 0) { -#ifdef SYSV - if (errno == EINTR) - continue; -#endif - if (errno != ENOENT && errno != ENOTDIR) - e = errno; - goto loop; - } - e = EACCES; /* if we fail, this will be the error */ - if (!S_ISREG(statb.st_mode)) - goto loop; - if (pathopt) { /* this is a %func directory */ - if (act & DO_NOFUNC) - goto loop; - stalloc(strlen(fullname) + 1); - readcmdfile(fullname); - if ((cmdp = cmdlookup(name, 0)) == NULL || - cmdp->cmdtype != CMDFUNCTION) - error("%s not defined in %s", name, fullname); - stunalloc(fullname); - goto success; - } -#ifdef notdef - /* XXX this code stops root executing stuff, and is buggy - if you need a group from the group list. */ - if (statb.st_uid == geteuid()) { - if ((statb.st_mode & 0100) == 0) - goto loop; - } else if (statb.st_gid == getegid()) { - if ((statb.st_mode & 010) == 0) - goto loop; - } else { - if ((statb.st_mode & 01) == 0) - goto loop; - } -#endif - TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); - INTOFF; - if (act & DO_ALTPATH) { - stalloc(strlen(fullname) + 1); - cmdp = &loc_cmd; - } else - cmdp = cmdlookup(name, 1); - cmdp->cmdtype = CMDNORMAL; - cmdp->param.index = idx; - INTON; - goto success; - } - - /* We failed. If there was an entry for this command, delete it */ - if (cmdp) - delete_cmd_entry(); - if (act & DO_ERR) - outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); - entry->cmdtype = CMDUNKNOWN; - return; - -builtin_success: - INTOFF; - if (act & DO_ALTPATH) - cmdp = &loc_cmd; - else - cmdp = cmdlookup(name, 1); - if (cmdp->cmdtype == CMDFUNCTION) - /* DO_NOFUNC must have been set */ - cmdp = &loc_cmd; - cmdp->cmdtype = CMDBUILTIN; - cmdp->param.bltin = bltin; - INTON; -success: - cmdp->rehash = 0; - entry->cmdtype = cmdp->cmdtype; - entry->u = cmdp->param; -} - - - -/* - * Search the table of builtin commands. - */ - -int -(*find_builtin(name))(int, char **) - char *name; -{ - const struct builtincmd *bp; - - for (bp = builtincmd ; bp->name ; bp++) { - if (*bp->name == *name && equal(bp->name, name)) - return bp->builtin; - } - return 0; -} - -int -(*find_splbltin(name))(int, char **) - char *name; -{ - const struct builtincmd *bp; - - for (bp = splbltincmd ; bp->name ; bp++) { - if (*bp->name == *name && equal(bp->name, name)) - return bp->builtin; - } - return 0; -} - -/* - * At shell startup put special builtins into hash table. - * ensures they are executed first (see posix). - * We stop functions being added with the same name - * (as they are impossible to call) - */ - -void -hash_special_builtins(void) -{ - const struct builtincmd *bp; - struct tblentry *cmdp; - - for (bp = splbltincmd ; bp->name ; bp++) { - cmdp = cmdlookup(bp->name, 1); - cmdp->cmdtype = CMDSPLBLTIN; - cmdp->param.bltin = bp->builtin; - } -} - - - -/* - * Called when a cd is done. Marks all commands so the next time they - * are executed they will be rehashed. - */ - -void -hashcd(void) -{ - struct tblentry **pp; - struct tblentry *cmdp; - - for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { - for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { - if (cmdp->cmdtype == CMDNORMAL - || (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) - cmdp->rehash = 1; - } - } -} - - - -/* - * Fix command hash table when PATH changed. - * Called before PATH is changed. The argument is the new value of PATH; - * pathval() still returns the old value at this point. - * Called with interrupts off. - */ - -void -changepath(const char *newval) -{ - const char *old, *new; - int idx; - int firstchange; - int bltin; - - old = pathval(); - new = newval; - firstchange = 9999; /* assume no change */ - idx = 0; - bltin = -1; - for (;;) { - if (*old != *new) { - firstchange = idx; - if ((*old == '\0' && *new == ':') - || (*old == ':' && *new == '\0')) - firstchange++; - old = new; /* ignore subsequent differences */ - } - if (*new == '\0') - break; - if (*new == '%' && bltin < 0 && prefix("builtin", new + 1)) - bltin = idx; - if (*new == ':') { - idx++; - } - new++, old++; - } - if (builtinloc < 0 && bltin >= 0) - builtinloc = bltin; /* zap builtins */ - if (builtinloc >= 0 && bltin < 0) - firstchange = 0; - clearcmdentry(firstchange); - builtinloc = bltin; -} - - -/* - * Clear out command entries. The argument specifies the first entry in - * PATH which has changed. - */ - -STATIC void -clearcmdentry(int firstchange) -{ - struct tblentry **tblp; - struct tblentry **pp; - struct tblentry *cmdp; - - INTOFF; - for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { - pp = tblp; - while ((cmdp = *pp) != NULL) { - if ((cmdp->cmdtype == CMDNORMAL && - cmdp->param.index >= firstchange) - || (cmdp->cmdtype == CMDBUILTIN && - builtinloc >= firstchange)) { - *pp = cmdp->next; - ckfree(cmdp); - } else { - pp = &cmdp->next; - } - } - } - INTON; -} - - -/* - * Delete all functions. - */ - -#ifdef mkinit -MKINIT void deletefuncs(void); -MKINIT void hash_special_builtins(void); - -INIT { - hash_special_builtins(); -} - -SHELLPROC { - deletefuncs(); -} -#endif - -void -deletefuncs(void) -{ - struct tblentry **tblp; - struct tblentry **pp; - struct tblentry *cmdp; - - INTOFF; - for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { - pp = tblp; - while ((cmdp = *pp) != NULL) { - if (cmdp->cmdtype == CMDFUNCTION) { - *pp = cmdp->next; - freefunc(cmdp->param.func); - ckfree(cmdp); - } else { - pp = &cmdp->next; - } - } - } - INTON; -} - - - -/* - * Locate a command in the command hash table. If "add" is nonzero, - * add the command to the table if it is not already present. The - * variable "lastcmdentry" is set to point to the address of the link - * pointing to the entry, so that delete_cmd_entry can delete the - * entry. - */ - -struct tblentry **lastcmdentry; - - -STATIC struct tblentry * -cmdlookup(const char *name, int add) -{ - int hashval; - const char *p; - struct tblentry *cmdp; - struct tblentry **pp; - - p = name; - hashval = *p << 4; - while (*p) - hashval += *p++; - hashval &= 0x7FFF; - pp = &cmdtable[hashval % CMDTABLESIZE]; - for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { - if (equal(cmdp->cmdname, name)) - break; - pp = &cmdp->next; - } - if (add && cmdp == NULL) { - INTOFF; - cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB - + strlen(name) + 1); - cmdp->next = NULL; - cmdp->cmdtype = CMDUNKNOWN; - cmdp->rehash = 0; - strcpy(cmdp->cmdname, name); - INTON; - } - lastcmdentry = pp; - return cmdp; -} - -/* - * Delete the command entry returned on the last lookup. - */ - -STATIC void -delete_cmd_entry(void) -{ - struct tblentry *cmdp; - - INTOFF; - cmdp = *lastcmdentry; - *lastcmdentry = cmdp->next; - ckfree(cmdp); - INTON; -} - - - -#ifdef notdef -void -getcmdentry(char *name, struct cmdentry *entry) -{ - struct tblentry *cmdp = cmdlookup(name, 0); - - if (cmdp) { - entry->u = cmdp->param; - entry->cmdtype = cmdp->cmdtype; - } else { - entry->cmdtype = CMDUNKNOWN; - entry->u.index = 0; - } -} -#endif - - -/* - * Add a new command entry, replacing any existing command entry for - * the same name - except special builtins. - */ - -STATIC void -addcmdentry(char *name, struct cmdentry *entry) -{ - struct tblentry *cmdp; - - INTOFF; - cmdp = cmdlookup(name, 1); - if (cmdp->cmdtype != CMDSPLBLTIN) { - if (cmdp->cmdtype == CMDFUNCTION) { - freefunc(cmdp->param.func); - } - cmdp->cmdtype = entry->cmdtype; - cmdp->param = entry->u; - } - INTON; -} - - -/* - * Define a shell function. - */ - -void -defun(char *name, union node *func) -{ - struct cmdentry entry; - - INTOFF; - entry.cmdtype = CMDFUNCTION; - entry.u.func = copyfunc(func); - addcmdentry(name, &entry); - INTON; -} - - -/* - * Delete a function if it exists. - */ - -int -unsetfunc(char *name) -{ - struct tblentry *cmdp; - - if ((cmdp = cmdlookup(name, 0)) != NULL && - cmdp->cmdtype == CMDFUNCTION) { - freefunc(cmdp->param.func); - delete_cmd_entry(); - return (0); - } - return (1); -} - -/* - * Locate and print what a word is... - * also used for 'command -[v|V]' - */ - -int -typecmd(int argc, char **argv) -{ - struct cmdentry entry; - struct tblentry *cmdp; - char * const *pp; - struct alias *ap; - int err = 0; - char *arg; - int c; - int V_flag = 0; - int v_flag = 0; - int p_flag = 0; - - while ((c = nextopt("vVp")) != 0) { - switch (c) { - case 'v': v_flag = 1; break; - case 'V': V_flag = 1; break; - case 'p': p_flag = 1; break; - } - } - - if (p_flag && (v_flag || V_flag)) - error("cannot specify -p with -v or -V"); - - while ((arg = *argptr++)) { - if (!v_flag) - out1str(arg); - /* First look at the keywords */ - for (pp = parsekwd; *pp; pp++) - if (**pp == *arg && equal(*pp, arg)) - break; - - if (*pp) { - if (v_flag) - err = 1; - else - out1str(" is a shell keyword\n"); - continue; - } - - /* Then look at the aliases */ - if ((ap = lookupalias(arg, 1)) != NULL) { - if (!v_flag) - out1fmt(" is an alias for \n"); - out1fmt("%s\n", ap->val); - continue; - } - - /* Then check if it is a tracked alias */ - if ((cmdp = cmdlookup(arg, 0)) != NULL) { - entry.cmdtype = cmdp->cmdtype; - entry.u = cmdp->param; - } else { - /* Finally use brute force */ - find_command(arg, &entry, DO_ABS, pathval()); - } - - switch (entry.cmdtype) { - case CMDNORMAL: { - if (strchr(arg, '/') == NULL) { - const char *path = pathval(); - char *name; - int j = entry.u.index; - do { - name = padvance(&path, arg); - stunalloc(name); - } while (--j >= 0); - if (!v_flag) - out1fmt(" is%s ", - cmdp ? " a tracked alias for" : ""); - out1fmt("%s\n", name); - } else { - if (access(arg, X_OK) == 0) { - if (!v_flag) - out1fmt(" is "); - out1fmt("%s\n", arg); - } else { - if (!v_flag) - out1fmt(": %s\n", - strerror(errno)); - else - err = 126; - } - } - break; - } - case CMDFUNCTION: - if (!v_flag) - out1str(" is a shell function\n"); - else - out1fmt("%s\n", arg); - break; - - case CMDBUILTIN: - if (!v_flag) - out1str(" is a shell builtin\n"); - else - out1fmt("%s\n", arg); - break; - - case CMDSPLBLTIN: - if (!v_flag) - out1str(" is a special shell builtin\n"); - else - out1fmt("%s\n", arg); - break; - - default: - if (!v_flag) - out1str(": not found\n"); - err = 127; - break; - } - } - return err; -} diff --git a/sh/exec.h b/sh/exec.h deleted file mode 100644 index 26fd09c34d845f9fafa5a4293bedd2427a938e06..0000000000000000000000000000000000000000 --- a/sh/exec.h +++ /dev/null @@ -1,79 +0,0 @@ -/* $NetBSD: exec.h,v 1.21 2003/08/07 09:05:31 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)exec.h 8.3 (Berkeley) 6/8/95 - */ - -/* values of cmdtype */ -#define CMDUNKNOWN -1 /* no entry in table for command */ -#define CMDNORMAL 0 /* command is an executable program */ -#define CMDFUNCTION 1 /* command is a shell function */ -#define CMDBUILTIN 2 /* command is a shell builtin */ -#define CMDSPLBLTIN 3 /* command is a special shell builtin */ - - -struct cmdentry { - int cmdtype; - union param { - int index; - int (*bltin)(int, char**); - union node *func; - } u; -}; - - -/* action to find_command() */ -#define DO_ERR 0x01 /* prints errors */ -#define DO_ABS 0x02 /* checks absolute paths */ -#define DO_NOFUNC 0x04 /* don't return shell functions, for command */ -#define DO_ALTPATH 0x08 /* using alternate path */ -#define DO_ALTBLTIN 0x20 /* %builtin in alt. path */ - -extern const char *pathopt; /* set by padvance */ - -void shellexec(char **, char **, const char *, int, int) - __attribute__((__noreturn__)); -char *padvance(const char **, const char *); -int hashcmd(int, char **); -void find_command(char *, struct cmdentry *, int, const char *); -int (*find_builtin(char *))(int, char **); -int (*find_splbltin(char *))(int, char **); -void hashcd(void); -void changepath(const char *); -void deletefuncs(void); -void getcmdentry(char *, struct cmdentry *); -void addcmdentry(char *, struct cmdentry *); -void defun(char *, union node *); -int unsetfunc(char *); -int typecmd(int, char **); -void hash_special_builtins(void); diff --git a/sh/expand.c b/sh/expand.c deleted file mode 100644 index d3462fcc03d72b46daaeaedc4ce3b469bbf5fe15..0000000000000000000000000000000000000000 --- a/sh/expand.c +++ /dev/null @@ -1,1559 +0,0 @@ -/* $NetBSD: expand.c,v 1.68.2.2 2005/04/07 11:37:39 tron Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; -#else -__RCSID("$NetBSD: expand.c,v 1.68.2.2 2005/04/07 11:37:39 tron Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/time.h> -#include <sys/stat.h> -#include <errno.h> -#include <dirent.h> -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> - -/* - * Routines to expand arguments to commands. We have to deal with - * backquotes, shell variables, and file metacharacters. - */ - -#include "shell.h" -#include "main.h" -#include "nodes.h" -#include "eval.h" -#include "expand.h" -#include "syntax.h" -#include "parser.h" -#include "jobs.h" -#include "options.h" -#include "var.h" -#include "input.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "mystring.h" -#include "show.h" - -/* - * Structure specifying which parts of the string should be searched - * for IFS characters. - */ - -struct ifsregion { - struct ifsregion *next; /* next region in list */ - int begoff; /* offset of start of region */ - int endoff; /* offset of end of region */ - int inquotes; /* search for nul bytes only */ -}; - - -char *expdest; /* output of current string */ -struct nodelist *argbackq; /* list of back quote expressions */ -struct ifsregion ifsfirst; /* first struct in list of ifs regions */ -struct ifsregion *ifslastp; /* last struct in list */ -struct arglist exparg; /* holds expanded arg list */ - -STATIC void argstr(char *, int); -STATIC char *exptilde(char *, int); -STATIC void expbackq(union node *, int, int); -STATIC int subevalvar(char *, char *, int, int, int, int); -STATIC char *evalvar(char *, int); -STATIC int varisset(char *, int); -STATIC void varvalue(char *, int, int, int); -STATIC void recordregion(int, int, int); -STATIC void removerecordregions(int); -STATIC void ifsbreakup(char *, struct arglist *); -STATIC void ifsfree(void); -STATIC void expandmeta(struct strlist *, int); -STATIC void expmeta(char *, char *); -STATIC void addfname(char *); -STATIC struct strlist *expsort(struct strlist *); -STATIC struct strlist *msort(struct strlist *, int); -STATIC int pmatch(char *, char *, int); -STATIC char *cvtnum(int, char *); - -/* - * Expand shell variables and backquotes inside a here document. - */ - -void -expandhere(union node *arg, int fd) -{ - herefd = fd; - expandarg(arg, (struct arglist *)NULL, 0); - xwrite(fd, stackblock(), expdest - stackblock()); -} - - -/* - * Perform variable substitution and command substitution on an argument, - * placing the resulting list of arguments in arglist. If EXP_FULL is true, - * perform splitting and file name expansion. When arglist is NULL, perform - * here document expansion. - */ - -void -expandarg(union node *arg, struct arglist *arglist, int flag) -{ - struct strlist *sp; - char *p; - - argbackq = arg->narg.backquote; - STARTSTACKSTR(expdest); - ifsfirst.next = NULL; - ifslastp = NULL; - argstr(arg->narg.text, flag); - if (arglist == NULL) { - return; /* here document expanded */ - } - STPUTC('\0', expdest); - p = grabstackstr(expdest); - exparg.lastp = &exparg.list; - /* - * TODO - EXP_REDIR - */ - if (flag & EXP_FULL) { - ifsbreakup(p, &exparg); - *exparg.lastp = NULL; - exparg.lastp = &exparg.list; - expandmeta(exparg.list, flag); - } else { - if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ - rmescapes(p); - sp = (struct strlist *)stalloc(sizeof (struct strlist)); - sp->text = p; - *exparg.lastp = sp; - exparg.lastp = &sp->next; - } - ifsfree(); - *exparg.lastp = NULL; - if (exparg.list) { - *arglist->lastp = exparg.list; - arglist->lastp = exparg.lastp; - } -} - - - -/* - * Perform variable and command substitution. - * If EXP_FULL is set, output CTLESC characters to allow for further processing. - * Otherwise treat $@ like $* since no splitting will be performed. - */ - -STATIC void -argstr(char *p, int flag) -{ - char c; - int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ - int firsteq = 1; - const char *ifs = 0; - int ifs_split = EXP_IFS_SPLIT; - - if (flag & EXP_IFS_SPLIT) - ifs = ifsset() ? ifsval() : " \t\n"; - - if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) - p = exptilde(p, flag); - for (;;) { - switch (c = *p++) { - case '\0': - case CTLENDVAR: /* end of expanding yyy in ${xxx-yyy} */ - return; - case CTLQUOTEMARK: - /* "$@" syntax adherence hack */ - if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=') - break; - if ((flag & EXP_FULL) != 0) - STPUTC(c, expdest); - ifs_split = 0; - break; - case CTLQUOTEEND: - ifs_split = EXP_IFS_SPLIT; - break; - case CTLESC: - if (quotes) - STPUTC(c, expdest); - c = *p++; - STPUTC(c, expdest); - break; - case CTLVAR: - p = evalvar(p, (flag & ~EXP_IFS_SPLIT) | (flag & ifs_split)); - break; - case CTLBACKQ: - case CTLBACKQ|CTLQUOTE: - expbackq(argbackq->n, c & CTLQUOTE, flag); - argbackq = argbackq->next; - break; - case CTLENDARI: - expari(flag); - break; - case ':': - case '=': - /* - * sort of a hack - expand tildes in variable - * assignments (after the first '=' and after ':'s). - */ - STPUTC(c, expdest); - if (flag & EXP_VARTILDE && *p == '~') { - if (c == '=') { - if (firsteq) - firsteq = 0; - else - break; - } - p = exptilde(p, flag); - } - break; - default: - STPUTC(c, expdest); - if (flag & EXP_IFS_SPLIT & ifs_split && strchr(ifs, c) != NULL) { - /* We need to get the output split here... */ - recordregion(expdest - stackblock() - 1, - expdest - stackblock(), 0); - } - break; - } - } -} - -STATIC char * -exptilde(char *p, int flag) -{ - char c, *startp = p; - const char *home; - int quotes = flag & (EXP_FULL | EXP_CASE); - - while ((c = *p) != '\0') { - switch(c) { - case CTLESC: - return (startp); - case CTLQUOTEMARK: - return (startp); - case ':': - if (flag & EXP_VARTILDE) - goto done; - break; - case '/': - goto done; - } - p++; - } -done: - *p = '\0'; - if (*(startp+1) == '\0') { - if ((home = lookupvar("HOME")) == NULL) - goto lose; - } else - goto lose; - if (*home == '\0') - goto lose; - *p = c; - while ((c = *home++) != '\0') { - if (quotes && SQSYNTAX[(int)c] == CCTL) - STPUTC(CTLESC, expdest); - STPUTC(c, expdest); - } - return (p); -lose: - *p = c; - return (startp); -} - - -STATIC void -removerecordregions(int endoff) -{ - if (ifslastp == NULL) - return; - - if (ifsfirst.endoff > endoff) { - while (ifsfirst.next != NULL) { - struct ifsregion *ifsp; - INTOFF; - ifsp = ifsfirst.next->next; - ckfree(ifsfirst.next); - ifsfirst.next = ifsp; - INTON; - } - if (ifsfirst.begoff > endoff) - ifslastp = NULL; - else { - ifslastp = &ifsfirst; - ifsfirst.endoff = endoff; - } - return; - } - - ifslastp = &ifsfirst; - while (ifslastp->next && ifslastp->next->begoff < endoff) - ifslastp=ifslastp->next; - while (ifslastp->next != NULL) { - struct ifsregion *ifsp; - INTOFF; - ifsp = ifslastp->next->next; - ckfree(ifslastp->next); - ifslastp->next = ifsp; - INTON; - } - if (ifslastp->endoff > endoff) - ifslastp->endoff = endoff; -} - - -/* - * Expand arithmetic expression. Backup to start of expression, - * evaluate, place result in (backed up) result, adjust string position. - */ -void -expari(int flag) -{ - char *p, *start; - int result; - int begoff; - int quotes = flag & (EXP_FULL | EXP_CASE); - int quoted; - - /* ifsfree(); */ - - /* - * This routine is slightly over-complicated for - * efficiency. First we make sure there is - * enough space for the result, which may be bigger - * than the expression if we add exponentation. Next we - * scan backwards looking for the start of arithmetic. If the - * next previous character is a CTLESC character, then we - * have to rescan starting from the beginning since CTLESC - * characters have to be processed left to right. - */ -#if INT_MAX / 1000000000 >= 10 || INT_MIN / 1000000000 <= -10 -#error "integers with more than 10 digits are not supported" -#endif - CHECKSTRSPACE(12 - 2, expdest); - USTPUTC('\0', expdest); - start = stackblock(); - p = expdest - 1; - while (*p != CTLARI && p >= start) - --p; - if (*p != CTLARI) - error("missing CTLARI (shouldn't happen)"); - if (p > start && *(p-1) == CTLESC) - for (p = start; *p != CTLARI; p++) - if (*p == CTLESC) - p++; - - if (p[1] == '"') - quoted=1; - else - quoted=0; - begoff = p - start; - removerecordregions(begoff); - if (quotes) - rmescapes(p+2); - result = arith(p+2); - fmtstr(p, 12, "%d", result); - - while (*p++) - ; - - if (quoted == 0) - recordregion(begoff, p - 1 - start, 0); - result = expdest - p + 1; - STADJUST(-result, expdest); -} - - -/* - * Expand stuff in backwards quotes. - */ - -STATIC void -expbackq(union node *cmd, int quoted, int flag) -{ - struct backcmd in; - int i; - char buf[128]; - char *p; - char *dest = expdest; - struct ifsregion saveifs, *savelastp; - struct nodelist *saveargbackq; - char lastc; - int startloc = dest - stackblock(); - char const *syntax = quoted? DQSYNTAX : BASESYNTAX; - int saveherefd; - int quotes = flag & (EXP_FULL | EXP_CASE); - - INTOFF; - saveifs = ifsfirst; - savelastp = ifslastp; - saveargbackq = argbackq; - saveherefd = herefd; - herefd = -1; - p = grabstackstr(dest); - evalbackcmd(cmd, &in); - ungrabstackstr(p, dest); - ifsfirst = saveifs; - ifslastp = savelastp; - argbackq = saveargbackq; - herefd = saveherefd; - - p = in.buf; - lastc = '\0'; - for (;;) { - if (--in.nleft < 0) { - if (in.fd < 0) - break; - while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR); - TRACE(("expbackq: read returns %d\n", i)); - if (i <= 0) - break; - p = buf; - in.nleft = i - 1; - } - lastc = *p++; - if (lastc != '\0') { - if (quotes && syntax[(int)lastc] == CCTL) - STPUTC(CTLESC, dest); - STPUTC(lastc, dest); - } - } - - /* Eat all trailing newlines */ - p = stackblock() + startloc; - while (dest > p && dest[-1] == '\n') - STUNPUTC(dest); - - if (in.fd >= 0) - close(in.fd); - if (in.buf) - ckfree(in.buf); - if (in.jp) - back_exitstatus = waitforjob(in.jp); - if (quoted == 0) - recordregion(startloc, dest - stackblock(), 0); - TRACE(("evalbackq: size=%d: \"%.*s\"\n", - (dest - stackblock()) - startloc, - (dest - stackblock()) - startloc, - stackblock() + startloc)); - expdest = dest; - INTON; -} - - - -STATIC int -subevalvar(char *p, char *str, int strloc, int subtype, int startloc, int varflags) -{ - char *startp; - char *loc = NULL; - char *q; - int c = 0; - int saveherefd = herefd; - struct nodelist *saveargbackq = argbackq; - int amount; - - herefd = -1; - argstr(p, 0); - STACKSTRNUL(expdest); - herefd = saveherefd; - argbackq = saveargbackq; - startp = stackblock() + startloc; - if (str == NULL) - str = stackblock() + strloc; - - switch (subtype) { - case VSASSIGN: - setvar(str, startp, 0); - amount = startp - expdest; - STADJUST(amount, expdest); - varflags &= ~VSNUL; - if (c != 0) - *loc = c; - return 1; - - case VSQUESTION: - if (*p != CTLENDVAR) { - outfmt(&errout, "%s\n", startp); - error((char *)NULL); - } - error("%.*s: parameter %snot set", p - str - 1, - str, (varflags & VSNUL) ? "null or " - : nullstr); - /* NOTREACHED */ - - case VSTRIMLEFT: - for (loc = startp; loc < str; loc++) { - c = *loc; - *loc = '\0'; - if (patmatch(str, startp, varflags & VSQUOTE)) - goto recordleft; - *loc = c; - if ((varflags & VSQUOTE) && *loc == CTLESC) - loc++; - } - return 0; - - case VSTRIMLEFTMAX: - for (loc = str - 1; loc >= startp;) { - c = *loc; - *loc = '\0'; - if (patmatch(str, startp, varflags & VSQUOTE)) - goto recordleft; - *loc = c; - loc--; - if ((varflags & VSQUOTE) && loc > startp && - *(loc - 1) == CTLESC) { - for (q = startp; q < loc; q++) - if (*q == CTLESC) - q++; - if (q > loc) - loc--; - } - } - return 0; - - case VSTRIMRIGHT: - for (loc = str - 1; loc >= startp;) { - if (patmatch(str, loc, varflags & VSQUOTE)) - goto recordright; - loc--; - if ((varflags & VSQUOTE) && loc > startp && - *(loc - 1) == CTLESC) { - for (q = startp; q < loc; q++) - if (*q == CTLESC) - q++; - if (q > loc) - loc--; - } - } - return 0; - - case VSTRIMRIGHTMAX: - for (loc = startp; loc < str - 1; loc++) { - if (patmatch(str, loc, varflags & VSQUOTE)) - goto recordright; - if ((varflags & VSQUOTE) && *loc == CTLESC) - loc++; - } - return 0; - - default: - abort(); - } - -recordleft: - *loc = c; - amount = ((str - 1) - (loc - startp)) - expdest; - STADJUST(amount, expdest); - while (loc != str - 1) - *startp++ = *loc++; - return 1; - -recordright: - amount = loc - expdest; - STADJUST(amount, expdest); - STPUTC('\0', expdest); - STADJUST(-1, expdest); - return 1; -} - - -/* - * Expand a variable, and return a pointer to the next character in the - * input string. - */ - -STATIC char * -evalvar(char *p, int flag) -{ - int subtype; - int varflags; - char *var; - char *val; - int patloc; - int c; - int set; - int special; - int startloc; - int varlen; - int apply_ifs; - int quotes = flag & (EXP_FULL | EXP_CASE); - - varflags = (unsigned char)*p++; - subtype = varflags & VSTYPE; - var = p; - special = !is_name(*p); - p = strchr(p, '=') + 1; - -again: /* jump here after setting a variable with ${var=text} */ - if (special) { - set = varisset(var, varflags & VSNUL); - val = NULL; - } else { - val = lookupvar(var); - if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) { - val = NULL; - set = 0; - } else - set = 1; - } - - varlen = 0; - startloc = expdest - stackblock(); - - if (!set && uflag) { - switch (subtype) { - case VSNORMAL: - case VSTRIMLEFT: - case VSTRIMLEFTMAX: - case VSTRIMRIGHT: - case VSTRIMRIGHTMAX: - case VSLENGTH: - error("%.*s: parameter not set", p - var - 1, var); - /* NOTREACHED */ - } - } - - if (set && subtype != VSPLUS) { - /* insert the value of the variable */ - if (special) { - varvalue(var, varflags & VSQUOTE, subtype, flag); - if (subtype == VSLENGTH) { - varlen = expdest - stackblock() - startloc; - STADJUST(-varlen, expdest); - } - } else { - char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX - : BASESYNTAX; - - if (subtype == VSLENGTH) { - for (;*val; val++) - varlen++; - } else { - while (*val) { - if (quotes && syntax[(int)*val] == CCTL) - STPUTC(CTLESC, expdest); - STPUTC(*val++, expdest); - } - - } - } - } - - - apply_ifs = ((varflags & VSQUOTE) == 0 || - (*var == '@' && shellparam.nparam != 1)); - - switch (subtype) { - case VSLENGTH: - expdest = cvtnum(varlen, expdest); - break; - - case VSNORMAL: - break; - - case VSPLUS: - set = !set; - /* FALLTHROUGH */ - case VSMINUS: - if (!set) { - argstr(p, flag | (apply_ifs ? EXP_IFS_SPLIT : 0)); - /* - * ${x-a b c} doesn't get split, but removing the - * 'apply_ifs = 0' apparantly breaks ${1+"$@"}.. - * ${x-'a b' c} should generate 2 args. - */ - /* We should have marked stuff already */ - apply_ifs = 0; - } - break; - - case VSTRIMLEFT: - case VSTRIMLEFTMAX: - case VSTRIMRIGHT: - case VSTRIMRIGHTMAX: - if (!set) - break; - /* - * Terminate the string and start recording the pattern - * right after it - */ - STPUTC('\0', expdest); - patloc = expdest - stackblock(); - if (subevalvar(p, NULL, patloc, subtype, - startloc, varflags) == 0) { - int amount = (expdest - stackblock() - patloc) + 1; - STADJUST(-amount, expdest); - } - /* Remove any recorded regions beyond start of variable */ - removerecordregions(startloc); - apply_ifs = 1; - break; - - case VSASSIGN: - case VSQUESTION: - if (set) - break; - if (subevalvar(p, var, 0, subtype, startloc, varflags)) { - varflags &= ~VSNUL; - /* - * Remove any recorded regions beyond - * start of variable - */ - removerecordregions(startloc); - goto again; - } - apply_ifs = 0; - break; - - default: - abort(); - } - - if (apply_ifs) - recordregion(startloc, expdest - stackblock(), - varflags & VSQUOTE); - - if (subtype != VSNORMAL) { /* skip to end of alternative */ - int nesting = 1; - for (;;) { - if ((c = *p++) == CTLESC) - p++; - else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { - if (set) - argbackq = argbackq->next; - } else if (c == CTLVAR) { - if ((*p++ & VSTYPE) != VSNORMAL) - nesting++; - } else if (c == CTLENDVAR) { - if (--nesting == 0) - break; - } - } - } - return p; -} - - - -/* - * Test whether a specialized variable is set. - */ - -STATIC int -varisset(char *name, int nulok) -{ - if (*name == '!') - return backgndpid != -1; - else if (*name == '@' || *name == '*') { - if (*shellparam.p == NULL) - return 0; - - if (nulok) { - char **av; - - for (av = shellparam.p; *av; av++) - if (**av != '\0') - return 1; - return 0; - } - } else if (is_digit(*name)) { - char *ap; - int num = atoi(name); - - if (num > shellparam.nparam) - return 0; - - if (num == 0) - ap = arg0; - else - ap = shellparam.p[num - 1]; - - if (nulok && (ap == NULL || *ap == '\0')) - return 0; - } - return 1; -} - - - -/* - * Add the value of a specialized variable to the stack string. - */ - -STATIC void -varvalue(char *name, int quoted, int subtype, int flag) -{ - int num; - char *p; - int i; - char sep; - char **ap; - char const *syntax; - -#define STRTODEST(p) \ - do {\ - if (flag & (EXP_FULL | EXP_CASE) && subtype != VSLENGTH) { \ - syntax = quoted? DQSYNTAX : BASESYNTAX; \ - while (*p) { \ - if (syntax[(int)*p] == CCTL) \ - STPUTC(CTLESC, expdest); \ - STPUTC(*p++, expdest); \ - } \ - } else \ - while (*p) \ - STPUTC(*p++, expdest); \ - } while (0) - - - switch (*name) { - case '$': - num = rootpid; - goto numvar; - case '?': - num = exitstatus; - goto numvar; - case '#': - num = shellparam.nparam; - goto numvar; - case '!': - num = backgndpid; -numvar: - expdest = cvtnum(num, expdest); - break; - case '-': - for (i = 0; optlist[i].name; i++) { - if (optlist[i].val) - STPUTC(optlist[i].letter, expdest); - } - break; - case '@': - if (flag & EXP_FULL && quoted) { - for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { - STRTODEST(p); - if (*ap) - STPUTC('\0', expdest); - } - break; - } - /* fall through */ - case '*': - if (ifsset() != 0) - sep = ifsval()[0]; - else - sep = ' '; - for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { - STRTODEST(p); - if (*ap && sep) - STPUTC(sep, expdest); - } - break; - case '0': - p = arg0; - STRTODEST(p); - break; - default: - if (is_digit(*name)) { - num = atoi(name); - if (num > 0 && num <= shellparam.nparam) { - p = shellparam.p[num - 1]; - STRTODEST(p); - } - } - break; - } -} - - - -/* - * Record the fact that we have to scan this region of the - * string for IFS characters. - */ - -STATIC void -recordregion(int start, int end, int inquotes) -{ - struct ifsregion *ifsp; - - if (ifslastp == NULL) { - ifsp = &ifsfirst; - } else { - if (ifslastp->endoff == start - && ifslastp->inquotes == inquotes) { - /* extend previous area */ - ifslastp->endoff = end; - return; - } - ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion)); - ifslastp->next = ifsp; - } - ifslastp = ifsp; - ifslastp->next = NULL; - ifslastp->begoff = start; - ifslastp->endoff = end; - ifslastp->inquotes = inquotes; -} - - - -/* - * Break the argument string into pieces based upon IFS and add the - * strings to the argument list. The regions of the string to be - * searched for IFS characters have been stored by recordregion. - */ -STATIC void -ifsbreakup(char *string, struct arglist *arglist) -{ - struct ifsregion *ifsp; - struct strlist *sp; - char *start; - char *p; - char *q; - const char *ifs; - const char *ifsspc; - int inquotes; - - start = string; - ifsspc = NULL; - inquotes = 0; - - if (ifslastp == NULL) { - /* Return entire argument, IFS doesn't apply to any of it */ - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = start; - *arglist->lastp = sp; - arglist->lastp = &sp->next; - return; - } - - ifs = ifsset() ? ifsval() : " \t\n"; - - for (ifsp = &ifsfirst; ifsp != NULL; ifsp = ifsp->next) { - p = string + ifsp->begoff; - inquotes = ifsp->inquotes; - ifsspc = NULL; - while (p < string + ifsp->endoff) { - q = p; - if (*p == CTLESC) - p++; - if (inquotes) { - /* Only NULs (probably from "$@") end args */ - if (*p != 0) { - p++; - continue; - } - } else { - if (!strchr(ifs, *p)) { - p++; - continue; - } - ifsspc = strchr(" \t\n", *p); - - /* Ignore IFS whitespace at start */ - if (q == start && ifsspc != NULL) { - p++; - start = p; - continue; - } - } - - /* Save this argument... */ - *q = '\0'; - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = start; - *arglist->lastp = sp; - arglist->lastp = &sp->next; - p++; - - if (ifsspc != NULL) { - /* Ignore further trailing IFS whitespace */ - for (; p < string + ifsp->endoff; p++) { - q = p; - if (*p == CTLESC) - p++; - if (strchr(ifs, *p) == NULL) { - p = q; - break; - } - if (strchr(" \t\n", *p) == NULL) { - p++; - break; - } - } - } - start = p; - } - } - - /* - * Save anything left as an argument. - * Traditionally we have treated 'IFS=':'; set -- x$IFS' as - * generating 2 arguments, the second of which is empty. - * Some recent clarification of the Posix spec say that it - * should only generate one.... - */ - if (*start /* || (!ifsspc && start > string) */) { - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = start; - *arglist->lastp = sp; - arglist->lastp = &sp->next; - } -} - -STATIC void -ifsfree(void) -{ - while (ifsfirst.next != NULL) { - struct ifsregion *ifsp; - INTOFF; - ifsp = ifsfirst.next->next; - ckfree(ifsfirst.next); - ifsfirst.next = ifsp; - INTON; - } - ifslastp = NULL; - ifsfirst.next = NULL; -} - - - -/* - * Expand shell metacharacters. At this point, the only control characters - * should be escapes. The results are stored in the list exparg. - */ - -char *expdir; - - -STATIC void -expandmeta(struct strlist *str, int flag) -{ - char *p; - struct strlist **savelastp; - struct strlist *sp; - char c; - /* TODO - EXP_REDIR */ - - while (str) { - if (fflag) - goto nometa; - p = str->text; - for (;;) { /* fast check for meta chars */ - if ((c = *p++) == '\0') - goto nometa; - if (c == '*' || c == '?' || c == '[' || c == '!') - break; - } - savelastp = exparg.lastp; - INTOFF; - if (expdir == NULL) { - int i = strlen(str->text); - expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */ - } - - expmeta(expdir, str->text); - ckfree(expdir); - expdir = NULL; - INTON; - if (exparg.lastp == savelastp) { - /* - * no matches - */ -nometa: - *exparg.lastp = str; - rmescapes(str->text); - exparg.lastp = &str->next; - } else { - *exparg.lastp = NULL; - *savelastp = sp = expsort(*savelastp); - while (sp->next != NULL) - sp = sp->next; - exparg.lastp = &sp->next; - } - str = str->next; - } -} - - -/* - * Do metacharacter (i.e. *, ?, [...]) expansion. - */ - -STATIC void -expmeta(char *enddir, char *name) -{ - char *p; - const char *cp; - char *q; - char *start; - char *endname; - int metaflag; - struct stat statb; - DIR *dirp; - struct dirent *dp; - int atend; - int matchdot; - - metaflag = 0; - start = name; - for (p = name ; ; p++) { - if (*p == '*' || *p == '?') - metaflag = 1; - else if (*p == '[') { - q = p + 1; - if (*q == '!') - q++; - for (;;) { - while (*q == CTLQUOTEMARK) - q++; - if (*q == CTLESC) - q++; - if (*q == '/' || *q == '\0') - break; - if (*++q == ']') { - metaflag = 1; - break; - } - } - } else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { - metaflag = 1; - } else if (*p == '\0') - break; - else if (*p == CTLQUOTEMARK) - continue; - else if (*p == CTLESC) - p++; - if (*p == '/') { - if (metaflag) - break; - start = p + 1; - } - } - if (metaflag == 0) { /* we've reached the end of the file name */ - if (enddir != expdir) - metaflag++; - for (p = name ; ; p++) { - if (*p == CTLQUOTEMARK) - continue; - if (*p == CTLESC) - p++; - *enddir++ = *p; - if (*p == '\0') - break; - } - if (metaflag == 0 || lstat(expdir, &statb) >= 0) - addfname(expdir); - return; - } - endname = p; - if (start != name) { - p = name; - while (p < start) { - while (*p == CTLQUOTEMARK) - p++; - if (*p == CTLESC) - p++; - *enddir++ = *p++; - } - } - if (enddir == expdir) { - cp = "."; - } else if (enddir == expdir + 1 && *expdir == '/') { - cp = "/"; - } else { - cp = expdir; - enddir[-1] = '\0'; - } - if ((dirp = opendir(cp)) == NULL) - return; - if (enddir != expdir) - enddir[-1] = '/'; - if (*endname == 0) { - atend = 1; - } else { - atend = 0; - *endname++ = '\0'; - } - matchdot = 0; - p = start; - while (*p == CTLQUOTEMARK) - p++; - if (*p == CTLESC) - p++; - if (*p == '.') - matchdot++; - while (! int_pending() && (dp = readdir(dirp)) != NULL) { - if (dp->d_name[0] == '.' && ! matchdot) - continue; - if (patmatch(start, dp->d_name, 0)) { - if (atend) { - scopy(dp->d_name, enddir); - addfname(expdir); - } else { - for (p = enddir, cp = dp->d_name; - (*p++ = *cp++) != '\0';) - continue; - p[-1] = '/'; - expmeta(p, endname); - } - } - } - closedir(dirp); - if (! atend) - endname[-1] = '/'; -} - - -/* - * Add a file name to the list. - */ - -STATIC void -addfname(char *name) -{ - char *p; - struct strlist *sp; - - p = stalloc(strlen(name) + 1); - scopy(name, p); - sp = (struct strlist *)stalloc(sizeof *sp); - sp->text = p; - *exparg.lastp = sp; - exparg.lastp = &sp->next; -} - - -/* - * Sort the results of file name expansion. It calculates the number of - * strings to sort and then calls msort (short for merge sort) to do the - * work. - */ - -STATIC struct strlist * -expsort(struct strlist *str) -{ - int len; - struct strlist *sp; - - len = 0; - for (sp = str ; sp ; sp = sp->next) - len++; - return msort(str, len); -} - - -STATIC struct strlist * -msort(struct strlist *list, int len) -{ - struct strlist *p, *q = NULL; - struct strlist **lpp; - int half; - int n; - - if (len <= 1) - return list; - half = len >> 1; - p = list; - for (n = half ; --n >= 0 ; ) { - q = p; - p = p->next; - } - q->next = NULL; /* terminate first half of list */ - q = msort(list, half); /* sort first half of list */ - p = msort(p, len - half); /* sort second half */ - lpp = &list; - for (;;) { - if (strcmp(p->text, q->text) < 0) { - *lpp = p; - lpp = &p->next; - if ((p = *lpp) == NULL) { - *lpp = q; - break; - } - } else { - *lpp = q; - lpp = &q->next; - if ((q = *lpp) == NULL) { - *lpp = p; - break; - } - } - } - return list; -} - - - -/* - * Returns true if the pattern matches the string. - */ - -int -patmatch(char *pattern, char *string, int squoted) -{ -#ifdef notdef - if (pattern[0] == '!' && pattern[1] == '!') - return 1 - pmatch(pattern + 2, string); - else -#endif - return pmatch(pattern, string, squoted); -} - - -STATIC int -pmatch(char *pattern, char *string, int squoted) -{ - char *p, *q; - char c; - - p = pattern; - q = string; - for (;;) { - switch (c = *p++) { - case '\0': - goto breakloop; - case CTLESC: - if (squoted && *q == CTLESC) - q++; - if (*q++ != *p++) - return 0; - break; - case CTLQUOTEMARK: - continue; - case '?': - if (squoted && *q == CTLESC) - q++; - if (*q++ == '\0') - return 0; - break; - case '*': - c = *p; - while (c == CTLQUOTEMARK || c == '*') - c = *++p; - if (c != CTLESC && c != CTLQUOTEMARK && - c != '?' && c != '*' && c != '[') { - while (*q != c) { - if (squoted && *q == CTLESC && - q[1] == c) - break; - if (*q == '\0') - return 0; - if (squoted && *q == CTLESC) - q++; - q++; - } - } - do { - if (pmatch(p, q, squoted)) - return 1; - if (squoted && *q == CTLESC) - q++; - } while (*q++ != '\0'); - return 0; - case '[': { - char *endp; - int invert, found; - char chr; - - endp = p; - if (*endp == '!') - endp++; - for (;;) { - while (*endp == CTLQUOTEMARK) - endp++; - if (*endp == '\0') - goto dft; /* no matching ] */ - if (*endp == CTLESC) - endp++; - if (*++endp == ']') - break; - } - invert = 0; - if (*p == '!') { - invert++; - p++; - } - found = 0; - chr = *q++; - if (squoted && chr == CTLESC) - chr = *q++; - if (chr == '\0') - return 0; - c = *p++; - do { - if (c == CTLQUOTEMARK) - continue; - if (c == CTLESC) - c = *p++; - if (*p == '-' && p[1] != ']') { - p++; - while (*p == CTLQUOTEMARK) - p++; - if (*p == CTLESC) - p++; - if (chr >= c && chr <= *p) - found = 1; - p++; - } else { - if (chr == c) - found = 1; - } - } while ((c = *p++) != ']'); - if (found == invert) - return 0; - break; - } -dft: default: - if (squoted && *q == CTLESC) - q++; - if (*q++ != c) - return 0; - break; - } - } -breakloop: - if (*q != '\0') - return 0; - return 1; -} - - - -/* - * Remove any CTLESC characters from a string. - */ - -void -rmescapes(char *str) -{ - char *p, *q; - - p = str; - while (*p != CTLESC && *p != CTLQUOTEMARK) { - if (*p++ == '\0') - return; - } - q = p; - while (*p) { - if (*p == CTLQUOTEMARK) { - p++; - continue; - } - if (*p == CTLESC) - p++; - *q++ = *p++; - } - *q = '\0'; -} - - - -/* - * See if a pattern matches in a case statement. - */ - -int -casematch(union node *pattern, char *val) -{ - struct stackmark smark; - int result; - char *p; - - setstackmark(&smark); - argbackq = pattern->narg.backquote; - STARTSTACKSTR(expdest); - ifslastp = NULL; - argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); - STPUTC('\0', expdest); - p = grabstackstr(expdest); - result = patmatch(p, val, 0); - popstackmark(&smark); - return result; -} - -/* - * Our own itoa(). - */ - -STATIC char * -cvtnum(int num, char *buf) -{ - char temp[32]; - int neg = num < 0; - char *p = temp + 31; - - temp[31] = '\0'; - - do { - *--p = num % 10 + '0'; - } while ((num /= 10) != 0); - - if (neg) - *--p = '-'; - - while (*p) - STPUTC(*p++, buf); - return buf; -} - -/* - * Do most of the work for wordexp(3). - */ - -int -wordexpcmd(int argc, char **argv) -{ - size_t len; - int i; - - out1fmt("%d", argc - 1); - out1c('\0'); - for (i = 1, len = 0; i < argc; i++) - len += strlen(argv[i]); - out1fmt("%zd", len); - out1c('\0'); - for (i = 1; i < argc; i++) { - out1str(argv[i]); - out1c('\0'); - } - return (0); -} diff --git a/sh/expand.h b/sh/expand.h deleted file mode 100644 index 1ea876d61034405a4820049a53d7402e4abeacf3..0000000000000000000000000000000000000000 --- a/sh/expand.h +++ /dev/null @@ -1,72 +0,0 @@ -/* $NetBSD: expand.h,v 1.16 2004/07/13 15:05:59 seb Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)expand.h 8.2 (Berkeley) 5/4/95 - */ - -struct strlist { - struct strlist *next; - char *text; -}; - - -struct arglist { - struct strlist *list; - struct strlist **lastp; -}; - -/* - * expandarg() flags - */ -#define EXP_FULL 0x1 /* perform word splitting & file globbing */ -#define EXP_TILDE 0x2 /* do normal tilde expansion */ -#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */ -#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */ -#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ -#define EXP_IFS_SPLIT 0x20 /* need to record arguments for ifs breakup */ - - -union node; -void expandhere(union node *, int); -void expandarg(union node *, struct arglist *, int); -void expari(int); -int patmatch(char *, char *, int); -void rmescapes(char *); -int casematch(union node *, char *); -int wordexpcmd(int, char **); - -/* From arith.y */ -int arith(const char *); -int expcmd(int , char **); -void arith_lex_reset(void); -int yylex(void); diff --git a/sh/funcs/cmv b/sh/funcs/cmv deleted file mode 100644 index 667f846e08a147a9166f2fafb7cdc58589a166a8..0000000000000000000000000000000000000000 --- a/sh/funcs/cmv +++ /dev/null @@ -1,50 +0,0 @@ -# $NetBSD: cmv,v 1.7 1995/05/11 21:31:05 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)cmv 8.2 (Berkeley) 5/4/95 - -# Conditional move--don't replace an existing file. - -cmv() { - if test $# != 2 - then echo "cmv: arg count" - return 2 - fi - if test -f "$2" -o -w "$2" - then echo "$2 exists" - return 2 - fi - /bin/mv "$1" "$2" -} diff --git a/sh/funcs/dirs b/sh/funcs/dirs deleted file mode 100644 index 68bb317bb7a61d8199aa5a5645bfdffc7490f7f7..0000000000000000000000000000000000000000 --- a/sh/funcs/dirs +++ /dev/null @@ -1,74 +0,0 @@ -# $NetBSD: dirs,v 1.7 1995/05/11 21:31:08 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)dirs 8.2 (Berkeley) 5/4/95 - -# pushd, popd, and dirs --- written by Chris Bertin -# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris -# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW - -pushd () { - SAVE=`pwd` - if [ "$1" = "" ] - then if [ "$DSTACK" = "" ] - then echo "pushd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 || return - shift 1 - DSTACK="$*" - else cd $1 > /dev/null || return - fi - DSTACK="$SAVE $DSTACK" - dirs -} - -popd () { - if [ "$DSTACK" = "" ] - then echo "popd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 - shift - DSTACK=$* - dirs -} - -dirs () { - echo "`pwd` $DSTACK" - return 0 -} diff --git a/sh/funcs/kill b/sh/funcs/kill deleted file mode 100644 index 75b0180bff7765e8eef631d4f1bef3e3acacbab1..0000000000000000000000000000000000000000 --- a/sh/funcs/kill +++ /dev/null @@ -1,50 +0,0 @@ -# $NetBSD: kill,v 1.7 1995/05/11 21:31:10 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)kill 8.2 (Berkeley) 5/4/95 - -# Convert job names to process ids and then run /bin/kill. - -kill() { - local args x - args= - for x in "$@" - do case $x in - %*) x=`jobid "$x"` ;; - esac - args="$args $x" - done - /bin/kill $args -} diff --git a/sh/funcs/login b/sh/funcs/login deleted file mode 100644 index 7ae08b2b037ec04f1b17014faf8b788ddebc0a79..0000000000000000000000000000000000000000 --- a/sh/funcs/login +++ /dev/null @@ -1,39 +0,0 @@ -# $NetBSD: login,v 1.7 1995/05/11 21:31:11 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)login 8.2 (Berkeley) 5/4/95 - -# replaces the login builtin in the BSD shell -login () exec login "$@" diff --git a/sh/funcs/newgrp b/sh/funcs/newgrp deleted file mode 100644 index 796a4f184e8cb8eaf3392b76a536d24bc5390cca..0000000000000000000000000000000000000000 --- a/sh/funcs/newgrp +++ /dev/null @@ -1,38 +0,0 @@ -# $NetBSD: newgrp,v 1.7 1995/05/11 21:31:12 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)newgrp 8.2 (Berkeley) 5/4/95 - -newgrp() exec newgrp "$@" diff --git a/sh/funcs/popd b/sh/funcs/popd deleted file mode 100644 index b2b65d5c2aad7c45939122d38932ecb13b22c974..0000000000000000000000000000000000000000 --- a/sh/funcs/popd +++ /dev/null @@ -1,74 +0,0 @@ -# $NetBSD: popd,v 1.7 1995/05/11 21:31:13 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)popd 8.2 (Berkeley) 5/4/95 - -# pushd, popd, and dirs --- written by Chris Bertin -# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris -# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW - -pushd () { - SAVE=`pwd` - if [ "$1" = "" ] - then if [ "$DSTACK" = "" ] - then echo "pushd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 || return - shift 1 - DSTACK="$*" - else cd $1 > /dev/null || return - fi - DSTACK="$SAVE $DSTACK" - dirs -} - -popd () { - if [ "$DSTACK" = "" ] - then echo "popd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 - shift - DSTACK=$* - dirs -} - -dirs () { - echo "`pwd` $DSTACK" - return 0 -} diff --git a/sh/funcs/pushd b/sh/funcs/pushd deleted file mode 100644 index b3930380c9961d9193e7bbdbbe9e4e41b38ffae9..0000000000000000000000000000000000000000 --- a/sh/funcs/pushd +++ /dev/null @@ -1,74 +0,0 @@ -# $NetBSD: pushd,v 1.7 1995/05/11 21:31:15 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)pushd 8.2 (Berkeley) 5/4/95 - -# pushd, popd, and dirs --- written by Chris Bertin -# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris -# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW - -pushd () { - SAVE=`pwd` - if [ "$1" = "" ] - then if [ "$DSTACK" = "" ] - then echo "pushd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 || return - shift 1 - DSTACK="$*" - else cd $1 > /dev/null || return - fi - DSTACK="$SAVE $DSTACK" - dirs -} - -popd () { - if [ "$DSTACK" = "" ] - then echo "popd: directory stack empty." - return 1 - fi - set $DSTACK - cd $1 - shift - DSTACK=$* - dirs -} - -dirs () { - echo "`pwd` $DSTACK" - return 0 -} diff --git a/sh/funcs/suspend b/sh/funcs/suspend deleted file mode 100644 index 8a4197dfef8c76223ceaa951bb19e89ed404b41d..0000000000000000000000000000000000000000 --- a/sh/funcs/suspend +++ /dev/null @@ -1,42 +0,0 @@ -# $NetBSD: suspend,v 1.7 1995/05/11 21:31:17 christos Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. All advertising materials mentioning features or use of this software -# must display the following acknowledgement: -# This product includes software developed by the University of -# California, Berkeley and its contributors. -# 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. -# -# @(#)suspend 8.2 (Berkeley) 5/4/95 - -suspend() { - local - - set +j - kill -TSTP 0 -} diff --git a/sh/histedit.c b/sh/histedit.c deleted file mode 100644 index 4bb2b34323273130b25c7d2d7af739aea054c64e..0000000000000000000000000000000000000000 --- a/sh/histedit.c +++ /dev/null @@ -1,540 +0,0 @@ -/* $NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem Exp $ */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: histedit.c,v 1.34 2003/10/27 06:19:29 lukem Exp $"); -#endif -#endif /* not lint */ - -#include <sys/param.h> -#include <paths.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -/* - * Editline and history functions (and glue). - */ -#include "shell.h" -#include "parser.h" -#include "var.h" -#include "options.h" -#include "main.h" -#include "output.h" -#include "mystring.h" -#include "myhistedit.h" -#include "error.h" -#ifndef SMALL -#include "eval.h" -#include "memalloc.h" - -#define MAXHISTLOOPS 4 /* max recursions through fc */ -#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */ - -History *hist; /* history cookie */ -EditLine *el; /* editline cookie */ -int displayhist; -static FILE *el_in, *el_out; - -STATIC const char *fc_replace(const char *, char *, char *); - -#ifdef DEBUG -extern FILE *tracefile; -#endif - -/* - * Set history and editing status. Called whenever the status may - * have changed (figures out what to do). - */ -void -histedit(void) -{ - FILE *el_err; - -#define editing (Eflag || Vflag) - - if (iflag) { - if (!hist) { - /* - * turn history on - */ - INTOFF; - hist = history_init(); - INTON; - - if (hist != NULL) - sethistsize(histsizeval()); - else - out2str("sh: can't initialize history\n"); - } - if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ - /* - * turn editing on - */ - char *term, *shname; - - INTOFF; - if (el_in == NULL) - el_in = fdopen(0, "r"); - if (el_out == NULL) - el_out = fdopen(2, "w"); - if (el_in == NULL || el_out == NULL) - goto bad; - el_err = el_out; -#if DEBUG - if (tracefile) - el_err = tracefile; -#endif - term = lookupvar("TERM"); - if (term) - setenv("TERM", term, 1); - else - unsetenv("TERM"); - shname = arg0; - if (shname[0] == '-') - shname++; - el = el_init(shname, el_in, el_out, el_err); - if (el != NULL) { - if (hist) - el_set(el, EL_HIST, history, hist); - el_set(el, EL_PROMPT, getprompt); - el_set(el, EL_SIGNAL, 1); - } else { -bad: - out2str("sh: can't initialize editing\n"); - } - INTON; - } else if (!editing && el) { - INTOFF; - el_end(el); - el = NULL; - INTON; - } - if (el) { - if (Vflag) - el_set(el, EL_EDITOR, "vi"); - else if (Eflag) - el_set(el, EL_EDITOR, "emacs"); - el_source(el, NULL); - } - } else { - INTOFF; - if (el) { /* no editing if not interactive */ - el_end(el); - el = NULL; - } - if (hist) { - history_end(hist); - hist = NULL; - } - INTON; - } -} - - -void -sethistsize(const char *hs) -{ - int histsize; - HistEvent he; - - if (hist != NULL) { - if (hs == NULL || *hs == '\0' || - (histsize = atoi(hs)) < 0) - histsize = 100; - history(hist, &he, H_SETSIZE, histsize); - } -} - -void -setterm(const char *term) -{ - if (el != NULL && term != NULL) - if (el_set(el, EL_TERMINAL, term) != 0) { - outfmt(out2, "sh: Can't set terminal type %s\n", term); - outfmt(out2, "sh: Using dumb terminal settings.\n"); - } -} - -int -inputrc(argc, argv) - int argc; - char **argv; -{ - if (argc != 2) { - out2str("usage: inputrc file\n"); - return 1; - } - if (el != NULL) { - if (el_source(el, argv[1])) { - out2str("inputrc: failed\n"); - return 1; - } else - return 0; - } else { - out2str("sh: inputrc ignored, not editing\n"); - return 1; - } -} - -/* - * This command is provided since POSIX decided to standardize - * the Korn shell fc command. Oh well... - */ -int -histcmd(int argc, char **argv) -{ - int ch; - const char *editor = NULL; - HistEvent he; - int lflg = 0, nflg = 0, rflg = 0, sflg = 0; - int i, retval; - const char *firststr, *laststr; - int first, last, direction; - char *pat = NULL, *repl; /* ksh "fc old=new" crap */ - static int active = 0; - struct jmploc jmploc; - struct jmploc *volatile savehandler; - char editfile[MAXPATHLEN + 1]; - FILE *efp; -#ifdef __GNUC__ - /* Avoid longjmp clobbering */ - (void) &editor; - (void) &lflg; - (void) &nflg; - (void) &rflg; - (void) &sflg; - (void) &firststr; - (void) &laststr; - (void) &pat; - (void) &repl; - (void) &efp; - (void) &argc; - (void) &argv; -#endif - - if (hist == NULL) - error("history not active"); - - if (argc == 1) - error("missing history argument"); - - optreset = 1; optind = 1; /* initialize getopt */ - while (not_fcnumber(argv[optind]) && - (ch = getopt(argc, argv, ":e:lnrs")) != -1) - switch ((char)ch) { - case 'e': - editor = optionarg; - break; - case 'l': - lflg = 1; - break; - case 'n': - nflg = 1; - break; - case 'r': - rflg = 1; - break; - case 's': - sflg = 1; - break; - case ':': - error("option -%c expects argument", optopt); - /* NOTREACHED */ - case '?': - default: - error("unknown option: -%c", optopt); - /* NOTREACHED */ - } - argc -= optind, argv += optind; - - /* - * If executing... - */ - if (lflg == 0 || editor || sflg) { - lflg = 0; /* ignore */ - editfile[0] = '\0'; - /* - * Catch interrupts to reset active counter and - * cleanup temp files. - */ - if (setjmp(jmploc.loc)) { - active = 0; - if (*editfile) - unlink(editfile); - handler = savehandler; - longjmp(handler->loc, 1); - } - savehandler = handler; - handler = &jmploc; - if (++active > MAXHISTLOOPS) { - active = 0; - displayhist = 0; - error("called recursively too many times"); - } - /* - * Set editor. - */ - if (sflg == 0) { - if (editor == NULL && - (editor = bltinlookup("FCEDIT", 1)) == NULL && - (editor = bltinlookup("EDITOR", 1)) == NULL) - editor = DEFEDITOR; - if (editor[0] == '-' && editor[1] == '\0') { - sflg = 1; /* no edit */ - editor = NULL; - } - } - } - - /* - * If executing, parse [old=new] now - */ - if (lflg == 0 && argc > 0 && - ((repl = strchr(argv[0], '=')) != NULL)) { - pat = argv[0]; - *repl++ = '\0'; - argc--, argv++; - } - /* - * determine [first] and [last] - */ - switch (argc) { - case 0: - firststr = lflg ? "-16" : "-1"; - laststr = "-1"; - break; - case 1: - firststr = argv[0]; - laststr = lflg ? "-1" : argv[0]; - break; - case 2: - firststr = argv[0]; - laststr = argv[1]; - break; - default: - error("too many args"); - /* NOTREACHED */ - } - /* - * Turn into event numbers. - */ - first = str_to_event(firststr, 0); - last = str_to_event(laststr, 1); - - if (rflg) { - i = last; - last = first; - first = i; - } - /* - * XXX - this should not depend on the event numbers - * always increasing. Add sequence numbers or offset - * to the history element in next (diskbased) release. - */ - direction = first < last ? H_PREV : H_NEXT; - - /* - * If editing, grab a temp file. - */ - if (editor) { - int fd; - INTOFF; /* easier */ - snprintf(editfile, sizeof(editfile), "%s_shXXXXXX", _PATH_TMP); - if ((fd = mkstemp(editfile)) < 0) - error("can't create temporary file %s", editfile); - if ((efp = fdopen(fd, "w")) == NULL) { - close(fd); - error("can't allocate stdio buffer for temp"); - } - } - - /* - * Loop through selected history events. If listing or executing, - * do it now. Otherwise, put into temp file and call the editor - * after. - * - * The history interface needs rethinking, as the following - * convolutions will demonstrate. - */ - history(hist, &he, H_FIRST); - retval = history(hist, &he, H_NEXT_EVENT, first); - for (;retval != -1; retval = history(hist, &he, direction)) { - if (lflg) { - if (!nflg) - out1fmt("%5d ", he.num); - out1str(he.str); - } else { - const char *s = pat ? - fc_replace(he.str, pat, repl) : he.str; - - if (sflg) { - if (displayhist) { - out2str(s); - } - - evalstring(strcpy(stalloc(strlen(s) + 1), s), 0); - if (displayhist && hist) { - /* - * XXX what about recursive and - * relative histnums. - */ - history(hist, &he, H_ENTER, s); - } - } else - fputs(s, efp); - } - /* - * At end? (if we were to lose last, we'd sure be - * messed up). - */ - if (he.num == last) - break; - } - if (editor) { - char *editcmd; - - fclose(efp); - editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); - sprintf(editcmd, "%s %s", editor, editfile); - evalstring(editcmd, 0); /* XXX - should use no JC command */ - INTON; - readcmdfile(editfile); /* XXX - should read back - quick tst */ - unlink(editfile); - } - - if (lflg == 0 && active > 0) - --active; - if (displayhist) - displayhist = 0; - return 0; -} - -STATIC const char * -fc_replace(const char *s, char *p, char *r) -{ - char *dest; - int plen = strlen(p); - - STARTSTACKSTR(dest); - while (*s) { - if (*s == *p && strncmp(s, p, plen) == 0) { - while (*r) - STPUTC(*r++, dest); - s += plen; - *p = '\0'; /* so no more matches */ - } else - STPUTC(*s++, dest); - } - STACKSTRNUL(dest); - dest = grabstackstr(dest); - - return (dest); -} - -int -not_fcnumber(char *s) -{ - if (s == NULL) - return 0; - if (*s == '-') - s++; - return (!is_number(s)); -} - -int -str_to_event(const char *str, int last) -{ - HistEvent he; - const char *s = str; - int relative = 0; - int i, retval; - - retval = history(hist, &he, H_FIRST); - switch (*s) { - case '-': - relative = 1; - /*FALLTHROUGH*/ - case '+': - s++; - } - if (is_number(s)) { - i = atoi(s); - if (relative) { - while (retval != -1 && i--) { - retval = history(hist, &he, H_NEXT); - } - if (retval == -1) - retval = history(hist, &he, H_LAST); - } else { - retval = history(hist, &he, H_NEXT_EVENT, i); - if (retval == -1) { - /* - * the notion of first and last is - * backwards to that of the history package - */ - retval = history(hist, &he, - last ? H_FIRST : H_LAST); - } - } - if (retval == -1) - error("history number %s not found (internal error)", - str); - } else { - /* - * pattern - */ - retval = history(hist, &he, H_PREV_STR, str); - if (retval == -1) - error("history pattern not found: %s", str); - } - return (he.num); -} -#else -int -histcmd(int argc, char **argv) -{ - error("not compiled with history support"); - /* NOTREACHED */ -} -int -inputrc(int argc, char **argv) -{ - error("not compiled with history support"); - /* NOTREACHED */ -} -#endif diff --git a/sh/init.c b/sh/init.c deleted file mode 100644 index 55ad17280438e1a1daddb6d943dafcc5a606b251..0000000000000000000000000000000000000000 --- a/sh/init.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * This file was generated by the mkinit program. - */ - -#include "shell.h" -#include "mystring.h" -#include "init.h" -#include "eval.h" -#include <stdio.h> -#include "input.h" -#include "error.h" -#include <stdlib.h> -#include "options.h" -#include "redir.h" -#include <signal.h> -#include "trap.h" -#include "output.h" -#include "memalloc.h" -#include "var.h" - - - -#undef ATABSIZE -#define ATABSIZE 39 -#undef YYBISON -#define YYBISON 1 -#undef YYSKELETON_NAME -#define YYSKELETON_NAME "yacc.c" -#undef YYPURE -#define YYPURE 0 -#undef YYLSP_NEEDED -#define YYLSP_NEEDED 0 -#undef ARITH_NUM -#define ARITH_NUM 258 -#undef ARITH_LPAREN -#define ARITH_LPAREN 259 -#undef ARITH_RPAREN -#define ARITH_RPAREN 260 -#undef ARITH_OR -#define ARITH_OR 261 -#undef ARITH_AND -#define ARITH_AND 262 -#undef ARITH_BOR -#define ARITH_BOR 263 -#undef ARITH_BXOR -#define ARITH_BXOR 264 -#undef ARITH_BAND -#define ARITH_BAND 265 -#undef ARITH_NE -#define ARITH_NE 266 -#undef ARITH_EQ -#define ARITH_EQ 267 -#undef ARITH_LE -#define ARITH_LE 268 -#undef ARITH_GE -#define ARITH_GE 269 -#undef ARITH_GT -#define ARITH_GT 270 -#undef ARITH_LT -#define ARITH_LT 271 -#undef ARITH_RSHIFT -#define ARITH_RSHIFT 272 -#undef ARITH_LSHIFT -#define ARITH_LSHIFT 273 -#undef ARITH_SUB -#define ARITH_SUB 274 -#undef ARITH_ADD -#define ARITH_ADD 275 -#undef ARITH_REM -#define ARITH_REM 276 -#undef ARITH_DIV -#define ARITH_DIV 277 -#undef ARITH_MUL -#define ARITH_MUL 278 -#undef ARITH_BNOT -#define ARITH_BNOT 279 -#undef ARITH_NOT -#define ARITH_NOT 280 -#undef ARITH_UNARYPLUS -#define ARITH_UNARYPLUS 281 -#undef ARITH_UNARYMINUS -#define ARITH_UNARYMINUS 282 -#undef YYFINAL -#define YYFINAL 14 -#undef YYLAST -#define YYLAST 170 -#undef YYNTOKENS -#define YYNTOKENS 28 -#undef YYNNTS -#define YYNNTS 3 -#undef YYNRULES -#define YYNRULES 26 -#undef YYNSTATES -#define YYNSTATES 52 -#undef YYUNDEFTOK -#define YYUNDEFTOK 2 -#undef YYMAXUTOK -#define YYMAXUTOK 282 -#undef YYPACT_NINF -#define YYPACT_NINF -13 -#undef YYTABLE_NINF -#define YYTABLE_NINF -1 -#undef yyerrok -#define yyerrok (yyerrstatus = 0) -#undef yyclearin -#define yyclearin (yychar = YYEMPTY) -#undef YYEMPTY -#define YYEMPTY (-2) -#undef YYEOF -#define YYEOF 0 -#undef YYACCEPT -#define YYACCEPT goto yyacceptlab -#undef YYABORT -#define YYABORT goto yyabortlab -#undef YYERROR -#define YYERROR goto yyerrorlab -#undef YYFAIL -#define YYFAIL goto yyerrlab -#undef YYTERROR -#define YYTERROR 1 -#undef YYERRCODE -#define YYERRCODE 256 -#undef YYPOPSTACK -#define YYPOPSTACK (yyvsp--, yyssp--) -#undef YY_INT_ALIGNED -#define YY_INT_ALIGNED short int -#undef FLEX_SCANNER -#define FLEX_SCANNER -#undef YY_FLEX_MAJOR_VERSION -#define YY_FLEX_MAJOR_VERSION 2 -#undef YY_FLEX_MINOR_VERSION -#define YY_FLEX_MINOR_VERSION 5 -#undef YY_FLEX_SUBMINOR_VERSION -#define YY_FLEX_SUBMINOR_VERSION 31 -#undef FLEX_BETA -#define FLEX_BETA -#undef FLEXINT_H -#define FLEXINT_H -#undef INT8_MIN -#define INT8_MIN (-128) -#undef INT16_MIN -#define INT16_MIN (-32767-1) -#undef INT32_MIN -#define INT32_MIN (-2147483647-1) -#undef INT8_MAX -#define INT8_MAX (127) -#undef INT16_MAX -#define INT16_MAX (32767) -#undef INT32_MAX -#define INT32_MAX (2147483647) -#undef UINT8_MAX -#define UINT8_MAX (255U) -#undef UINT16_MAX -#define UINT16_MAX (65535U) -#undef UINT32_MAX -#define UINT32_MAX (4294967295U) -#undef YY_USE_CONST -#define YY_USE_CONST -#undef YY_USE_CONST -#define YY_USE_CONST -#undef yyconst -#define yyconst const -#undef yyconst -#define yyconst -#undef YY_NULL -#define YY_NULL 0 -#undef BEGIN -#define BEGIN (yy_start) = 1 + 2 * -#undef YY_START -#define YY_START (((yy_start) - 1) / 2) -#undef YYSTATE -#define YYSTATE YY_START -#undef YY_NEW_FILE -#define YY_NEW_FILE yyrestart(yyin ) -#undef YY_END_OF_BUFFER_CHAR -#define YY_END_OF_BUFFER_CHAR 0 -#undef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#undef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -#undef EOB_ACT_CONTINUE_SCAN -#define EOB_ACT_CONTINUE_SCAN 0 -#undef EOB_ACT_END_OF_FILE -#define EOB_ACT_END_OF_FILE 1 -#undef EOB_ACT_LAST_MATCH -#define EOB_ACT_LAST_MATCH 2 -#undef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -#undef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -#undef YY_BUFFER_NEW -#define YY_BUFFER_NEW 0 -#undef YY_BUFFER_NORMAL -#define YY_BUFFER_NORMAL 1 -#undef YY_BUFFER_EOF_PENDING -#define YY_BUFFER_EOF_PENDING 2 -#undef YY_CURRENT_BUFFER -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -#undef YY_CURRENT_BUFFER_LVALUE -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] -#undef YY_FLUSH_BUFFER -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -#undef yy_new_buffer -#define yy_new_buffer yy_create_buffer -#undef YY_SKIP_YYWRAP -#define YY_SKIP_YYWRAP -#undef yytext_ptr -#define yytext_ptr yytext -#undef YY_DO_BEFORE_ACTION -#define YY_DO_BEFORE_ACTION \ -#undef YY_NUM_RULES -#define YY_NUM_RULES 29 -#undef YY_END_OF_BUFFER -#define YY_END_OF_BUFFER 30 -#undef REJECT -#define REJECT reject_used_but_not_detected -#undef YY_MORE_ADJ -#define YY_MORE_ADJ 0 -#undef YY_RESTORE_YY_MORE_OFFSET -#define YY_RESTORE_YY_MORE_OFFSET -#undef YY_NO_UNPUT -#define YY_NO_UNPUT -#undef INITIAL -#define INITIAL 0 -#undef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#undef ECHO -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#undef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#undef YY_DECL_IS_OURS -#define YY_DECL_IS_OURS 1 -#undef YY_DECL -#define YY_DECL int yylex (void) -#undef YY_USER_ACTION -#define YY_USER_ACTION -#undef YY_BREAK -#define YY_BREAK break; -#undef YY_RULE_SETUP -#define YY_RULE_SETUP \ -#undef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#undef YYTABLES_NAME -#define YYTABLES_NAME "yytables" -#undef MAXPWD -#define MAXPWD 256 -#undef signal -#define signal bsd_signal -#undef ALL -#define ALL (E_OPEN|E_CREAT|E_EXEC) -#undef EV_EXIT -#define EV_EXIT 01 /* exit after evaluating tree */ -#undef EV_TESTED -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ -#undef EV_BACKCMD -#define EV_BACKCMD 04 /* command executing within back quotes */ -#undef CMDTABLESIZE -#define CMDTABLESIZE 31 /* should be prime */ -#undef ARB -#define ARB 1 /* actual size determined at run time */ -#undef NEWARGS -#define NEWARGS 5 -#undef EOF_NLEFT -#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ -#undef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#undef PROFILE -#define PROFILE 0 -#undef SIGSSIZE -#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) -#undef MINSIZE -#define MINSIZE 504 /* minimum size of a block */ -#undef DEFINE_OPTIONS -#define DEFINE_OPTIONS -#undef EOFMARKLEN -#define EOFMARKLEN 79 -#undef OPENBRACE -#define OPENBRACE '{' -#undef CLOSEBRACE -#define CLOSEBRACE '}' -#undef EMPTY -#define EMPTY -2 /* marks an unused slot in redirtab */ -#undef signal -#define signal bsd_signal -#undef sys_signame -#define sys_signame sys_siglist -#undef S_DFL -#define S_DFL 1 /* default signal handling (SIG_DFL) */ -#undef S_CATCH -#define S_CATCH 2 /* signal is caught */ -#undef S_IGN -#define S_IGN 3 /* signal is ignored (SIG_IGN) */ -#undef S_HARD_IGN -#define S_HARD_IGN 4 /* signal is ignored permenantly */ -#undef S_RESET -#define S_RESET 5 /* temporary - to reset a hard ignored sig */ -#undef OUTBUFSIZ -#define OUTBUFSIZ BUFSIZ -#undef BLOCK_OUT -#define BLOCK_OUT -2 /* output to a fixed block of memory */ -#undef MEM_OUT -#define MEM_OUT -3 /* output to dynamically allocated memory */ -#undef OUTPUT_ERR -#define OUTPUT_ERR 01 /* error occurred on output */ -#undef TEMPSIZE -#define TEMPSIZE 24 -#undef HAVE_VASPRINTF -#define HAVE_VASPRINTF 1 -#undef VTABSIZE -#define VTABSIZE 39 -#undef VTABSIZE -#define VTABSIZE 517 -#undef ATABSIZE -#define ATABSIZE 39 -#undef YYBISON -#define YYBISON 1 -#undef YYSKELETON_NAME -#define YYSKELETON_NAME "yacc.c" -#undef YYPURE -#define YYPURE 0 -#undef YYLSP_NEEDED -#define YYLSP_NEEDED 0 -#undef ARITH_NUM -#define ARITH_NUM 258 -#undef ARITH_LPAREN -#define ARITH_LPAREN 259 -#undef ARITH_RPAREN -#define ARITH_RPAREN 260 -#undef ARITH_OR -#define ARITH_OR 261 -#undef ARITH_AND -#define ARITH_AND 262 -#undef ARITH_BOR -#define ARITH_BOR 263 -#undef ARITH_BXOR -#define ARITH_BXOR 264 -#undef ARITH_BAND -#define ARITH_BAND 265 -#undef ARITH_NE -#define ARITH_NE 266 -#undef ARITH_EQ -#define ARITH_EQ 267 -#undef ARITH_LE -#define ARITH_LE 268 -#undef ARITH_GE -#define ARITH_GE 269 -#undef ARITH_GT -#define ARITH_GT 270 -#undef ARITH_LT -#define ARITH_LT 271 -#undef ARITH_RSHIFT -#define ARITH_RSHIFT 272 -#undef ARITH_LSHIFT -#define ARITH_LSHIFT 273 -#undef ARITH_SUB -#define ARITH_SUB 274 -#undef ARITH_ADD -#define ARITH_ADD 275 -#undef ARITH_REM -#define ARITH_REM 276 -#undef ARITH_DIV -#define ARITH_DIV 277 -#undef ARITH_MUL -#define ARITH_MUL 278 -#undef ARITH_BNOT -#define ARITH_BNOT 279 -#undef ARITH_NOT -#define ARITH_NOT 280 -#undef ARITH_UNARYPLUS -#define ARITH_UNARYPLUS 281 -#undef ARITH_UNARYMINUS -#define ARITH_UNARYMINUS 282 -#undef YYFINAL -#define YYFINAL 14 -#undef YYLAST -#define YYLAST 170 -#undef YYNTOKENS -#define YYNTOKENS 28 -#undef YYNNTS -#define YYNNTS 3 -#undef YYNRULES -#define YYNRULES 26 -#undef YYNSTATES -#define YYNSTATES 52 -#undef YYUNDEFTOK -#define YYUNDEFTOK 2 -#undef YYMAXUTOK -#define YYMAXUTOK 282 -#undef YYPACT_NINF -#define YYPACT_NINF -13 -#undef YYTABLE_NINF -#define YYTABLE_NINF -1 -#undef yyerrok -#define yyerrok (yyerrstatus = 0) -#undef yyclearin -#define yyclearin (yychar = YYEMPTY) -#undef YYEMPTY -#define YYEMPTY (-2) -#undef YYEOF -#define YYEOF 0 -#undef YYACCEPT -#define YYACCEPT goto yyacceptlab -#undef YYABORT -#define YYABORT goto yyabortlab -#undef YYERROR -#define YYERROR goto yyerrorlab -#undef YYFAIL -#define YYFAIL goto yyerrlab -#undef YYTERROR -#define YYTERROR 1 -#undef YYERRCODE -#define YYERRCODE 256 -#undef YYPOPSTACK -#define YYPOPSTACK (yyvsp--, yyssp--) -#undef YY_INT_ALIGNED -#define YY_INT_ALIGNED short int -#undef FLEX_SCANNER -#define FLEX_SCANNER -#undef YY_FLEX_MAJOR_VERSION -#define YY_FLEX_MAJOR_VERSION 2 -#undef YY_FLEX_MINOR_VERSION -#define YY_FLEX_MINOR_VERSION 5 -#undef YY_FLEX_SUBMINOR_VERSION -#define YY_FLEX_SUBMINOR_VERSION 31 -#undef FLEX_BETA -#define FLEX_BETA -#undef FLEXINT_H -#define FLEXINT_H -#undef INT8_MIN -#define INT8_MIN (-128) -#undef INT16_MIN -#define INT16_MIN (-32767-1) -#undef INT32_MIN -#define INT32_MIN (-2147483647-1) -#undef INT8_MAX -#define INT8_MAX (127) -#undef INT16_MAX -#define INT16_MAX (32767) -#undef INT32_MAX -#define INT32_MAX (2147483647) -#undef UINT8_MAX -#define UINT8_MAX (255U) -#undef UINT16_MAX -#define UINT16_MAX (65535U) -#undef UINT32_MAX -#define UINT32_MAX (4294967295U) -#undef YY_USE_CONST -#define YY_USE_CONST -#undef YY_USE_CONST -#define YY_USE_CONST -#undef yyconst -#define yyconst const -#undef yyconst -#define yyconst -#undef YY_NULL -#define YY_NULL 0 -#undef BEGIN -#define BEGIN (yy_start) = 1 + 2 * -#undef YY_START -#define YY_START (((yy_start) - 1) / 2) -#undef YYSTATE -#define YYSTATE YY_START -#undef YY_NEW_FILE -#define YY_NEW_FILE yyrestart(yyin ) -#undef YY_END_OF_BUFFER_CHAR -#define YY_END_OF_BUFFER_CHAR 0 -#undef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#undef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -#undef EOB_ACT_CONTINUE_SCAN -#define EOB_ACT_CONTINUE_SCAN 0 -#undef EOB_ACT_END_OF_FILE -#define EOB_ACT_END_OF_FILE 1 -#undef EOB_ACT_LAST_MATCH -#define EOB_ACT_LAST_MATCH 2 -#undef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -#undef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -#undef YY_BUFFER_NEW -#define YY_BUFFER_NEW 0 -#undef YY_BUFFER_NORMAL -#define YY_BUFFER_NORMAL 1 -#undef YY_BUFFER_EOF_PENDING -#define YY_BUFFER_EOF_PENDING 2 -#undef YY_CURRENT_BUFFER -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -#undef YY_CURRENT_BUFFER_LVALUE -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] -#undef YY_FLUSH_BUFFER -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -#undef yy_new_buffer -#define yy_new_buffer yy_create_buffer -#undef YY_SKIP_YYWRAP -#define YY_SKIP_YYWRAP -#undef yytext_ptr -#define yytext_ptr yytext -#undef YY_DO_BEFORE_ACTION -#define YY_DO_BEFORE_ACTION \ -#undef YY_NUM_RULES -#define YY_NUM_RULES 29 -#undef YY_END_OF_BUFFER -#define YY_END_OF_BUFFER 30 -#undef REJECT -#define REJECT reject_used_but_not_detected -#undef YY_MORE_ADJ -#define YY_MORE_ADJ 0 -#undef YY_RESTORE_YY_MORE_OFFSET -#define YY_RESTORE_YY_MORE_OFFSET -#undef YY_NO_UNPUT -#define YY_NO_UNPUT -#undef INITIAL -#define INITIAL 0 -#undef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#undef ECHO -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#undef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#undef YY_DECL_IS_OURS -#define YY_DECL_IS_OURS 1 -#undef YY_DECL -#define YY_DECL int yylex (void) -#undef YY_USER_ACTION -#define YY_USER_ACTION -#undef YY_BREAK -#define YY_BREAK break; -#undef YY_RULE_SETUP -#define YY_RULE_SETUP \ -#undef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#undef YYTABLES_NAME -#define YYTABLES_NAME "yytables" -#undef MAXPWD -#define MAXPWD 256 -#undef signal -#define signal bsd_signal -#undef ALL -#define ALL (E_OPEN|E_CREAT|E_EXEC) -#undef EV_EXIT -#define EV_EXIT 01 /* exit after evaluating tree */ -#undef EV_TESTED -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ -#undef EV_BACKCMD -#define EV_BACKCMD 04 /* command executing within back quotes */ -#undef CMDTABLESIZE -#define CMDTABLESIZE 31 /* should be prime */ -#undef ARB -#define ARB 1 /* actual size determined at run time */ -#undef NEWARGS -#define NEWARGS 5 -#undef EOF_NLEFT -#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ -#undef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#undef PROFILE -#define PROFILE 0 -#undef SIGSSIZE -#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) -#undef MINSIZE -#define MINSIZE 504 /* minimum size of a block */ -#undef DEFINE_OPTIONS -#define DEFINE_OPTIONS -#undef EOFMARKLEN -#define EOFMARKLEN 79 -#undef OPENBRACE -#define OPENBRACE '{' -#undef CLOSEBRACE -#define CLOSEBRACE '}' -#undef EMPTY -#define EMPTY -2 /* marks an unused slot in redirtab */ -#undef signal -#define signal bsd_signal -#undef sys_signame -#define sys_signame sys_siglist -#undef S_DFL -#define S_DFL 1 /* default signal handling (SIG_DFL) */ -#undef S_CATCH -#define S_CATCH 2 /* signal is caught */ -#undef S_IGN -#define S_IGN 3 /* signal is ignored (SIG_IGN) */ -#undef S_HARD_IGN -#define S_HARD_IGN 4 /* signal is ignored permenantly */ -#undef S_RESET -#define S_RESET 5 /* temporary - to reset a hard ignored sig */ -#undef OUTBUFSIZ -#define OUTBUFSIZ BUFSIZ -#undef BLOCK_OUT -#define BLOCK_OUT -2 /* output to a fixed block of memory */ -#undef MEM_OUT -#define MEM_OUT -3 /* output to dynamically allocated memory */ -#undef OUTPUT_ERR -#define OUTPUT_ERR 01 /* error occurred on output */ -#undef TEMPSIZE -#define TEMPSIZE 24 -#undef HAVE_VASPRINTF -#define HAVE_VASPRINTF 1 -#undef VTABSIZE -#define VTABSIZE 39 -#undef VTABSIZE -#define VTABSIZE 517 -#undef main -#define main echocmd -#undef YYBISON -#define YYBISON 1 -#undef YYSKELETON_NAME -#define YYSKELETON_NAME "yacc.c" -#undef YYPURE -#define YYPURE 0 -#undef YYLSP_NEEDED -#define YYLSP_NEEDED 0 -#undef ARITH_NUM -#define ARITH_NUM 258 -#undef ARITH_LPAREN -#define ARITH_LPAREN 259 -#undef ARITH_RPAREN -#define ARITH_RPAREN 260 -#undef ARITH_OR -#define ARITH_OR 261 -#undef ARITH_AND -#define ARITH_AND 262 -#undef ARITH_BOR -#define ARITH_BOR 263 -#undef ARITH_BXOR -#define ARITH_BXOR 264 -#undef ARITH_BAND -#define ARITH_BAND 265 -#undef ARITH_NE -#define ARITH_NE 266 -#undef ARITH_EQ -#define ARITH_EQ 267 -#undef ARITH_LE -#define ARITH_LE 268 -#undef ARITH_GE -#define ARITH_GE 269 -#undef ARITH_GT -#define ARITH_GT 270 -#undef ARITH_LT -#define ARITH_LT 271 -#undef ARITH_RSHIFT -#define ARITH_RSHIFT 272 -#undef ARITH_LSHIFT -#define ARITH_LSHIFT 273 -#undef ARITH_SUB -#define ARITH_SUB 274 -#undef ARITH_ADD -#define ARITH_ADD 275 -#undef ARITH_REM -#define ARITH_REM 276 -#undef ARITH_DIV -#define ARITH_DIV 277 -#undef ARITH_MUL -#define ARITH_MUL 278 -#undef ARITH_BNOT -#define ARITH_BNOT 279 -#undef ARITH_NOT -#define ARITH_NOT 280 -#undef ARITH_UNARYPLUS -#define ARITH_UNARYPLUS 281 -#undef ARITH_UNARYMINUS -#define ARITH_UNARYMINUS 282 -#undef YYFINAL -#define YYFINAL 14 -#undef YYLAST -#define YYLAST 170 -#undef YYNTOKENS -#define YYNTOKENS 28 -#undef YYNNTS -#define YYNNTS 3 -#undef YYNRULES -#define YYNRULES 26 -#undef YYNSTATES -#define YYNSTATES 52 -#undef YYUNDEFTOK -#define YYUNDEFTOK 2 -#undef YYMAXUTOK -#define YYMAXUTOK 282 -#undef YYPACT_NINF -#define YYPACT_NINF -13 -#undef YYTABLE_NINF -#define YYTABLE_NINF -1 -#undef yyerrok -#define yyerrok (yyerrstatus = 0) -#undef yyclearin -#define yyclearin (yychar = YYEMPTY) -#undef YYEMPTY -#define YYEMPTY (-2) -#undef YYEOF -#define YYEOF 0 -#undef YYACCEPT -#define YYACCEPT goto yyacceptlab -#undef YYABORT -#define YYABORT goto yyabortlab -#undef YYERROR -#define YYERROR goto yyerrorlab -#undef YYFAIL -#define YYFAIL goto yyerrlab -#undef YYTERROR -#define YYTERROR 1 -#undef YYERRCODE -#define YYERRCODE 256 -#undef YYPOPSTACK -#define YYPOPSTACK (yyvsp--, yyssp--) -#undef YY_INT_ALIGNED -#define YY_INT_ALIGNED short int -#undef FLEX_SCANNER -#define FLEX_SCANNER -#undef YY_FLEX_MAJOR_VERSION -#define YY_FLEX_MAJOR_VERSION 2 -#undef YY_FLEX_MINOR_VERSION -#define YY_FLEX_MINOR_VERSION 5 -#undef YY_FLEX_SUBMINOR_VERSION -#define YY_FLEX_SUBMINOR_VERSION 31 -#undef FLEX_BETA -#define FLEX_BETA -#undef FLEXINT_H -#define FLEXINT_H -#undef INT8_MIN -#define INT8_MIN (-128) -#undef INT16_MIN -#define INT16_MIN (-32767-1) -#undef INT32_MIN -#define INT32_MIN (-2147483647-1) -#undef INT8_MAX -#define INT8_MAX (127) -#undef INT16_MAX -#define INT16_MAX (32767) -#undef INT32_MAX -#define INT32_MAX (2147483647) -#undef UINT8_MAX -#define UINT8_MAX (255U) -#undef UINT16_MAX -#define UINT16_MAX (65535U) -#undef UINT32_MAX -#define UINT32_MAX (4294967295U) -#undef YY_USE_CONST -#define YY_USE_CONST -#undef YY_USE_CONST -#define YY_USE_CONST -#undef yyconst -#define yyconst const -#undef yyconst -#define yyconst -#undef YY_NULL -#define YY_NULL 0 -#undef BEGIN -#define BEGIN (yy_start) = 1 + 2 * -#undef YY_START -#define YY_START (((yy_start) - 1) / 2) -#undef YYSTATE -#define YYSTATE YY_START -#undef YY_NEW_FILE -#define YY_NEW_FILE yyrestart(yyin ) -#undef YY_END_OF_BUFFER_CHAR -#define YY_END_OF_BUFFER_CHAR 0 -#undef YY_BUF_SIZE -#define YY_BUF_SIZE 16384 -#undef YY_TYPEDEF_YY_BUFFER_STATE -#define YY_TYPEDEF_YY_BUFFER_STATE -#undef EOB_ACT_CONTINUE_SCAN -#define EOB_ACT_CONTINUE_SCAN 0 -#undef EOB_ACT_END_OF_FILE -#define EOB_ACT_END_OF_FILE 1 -#undef EOB_ACT_LAST_MATCH -#define EOB_ACT_LAST_MATCH 2 -#undef YY_TYPEDEF_YY_SIZE_T -#define YY_TYPEDEF_YY_SIZE_T -#undef YY_STRUCT_YY_BUFFER_STATE -#define YY_STRUCT_YY_BUFFER_STATE -#undef YY_BUFFER_NEW -#define YY_BUFFER_NEW 0 -#undef YY_BUFFER_NORMAL -#define YY_BUFFER_NORMAL 1 -#undef YY_BUFFER_EOF_PENDING -#define YY_BUFFER_EOF_PENDING 2 -#undef YY_CURRENT_BUFFER -#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ -#undef YY_CURRENT_BUFFER_LVALUE -#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] -#undef YY_FLUSH_BUFFER -#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) -#undef yy_new_buffer -#define yy_new_buffer yy_create_buffer -#undef yytext_ptr -#define yytext_ptr yytext -#undef YY_DO_BEFORE_ACTION -#define YY_DO_BEFORE_ACTION \ -#undef YY_NUM_RULES -#define YY_NUM_RULES 29 -#undef YY_END_OF_BUFFER -#define YY_END_OF_BUFFER 30 -#undef REJECT -#define REJECT reject_used_but_not_detected -#undef YY_MORE_ADJ -#define YY_MORE_ADJ 0 -#undef YY_RESTORE_YY_MORE_OFFSET -#define YY_RESTORE_YY_MORE_OFFSET -#undef YY_NO_UNPUT -#define YY_NO_UNPUT -#undef INITIAL -#define INITIAL 0 -#undef YY_EXTRA_TYPE -#define YY_EXTRA_TYPE void * -#undef YY_READ_BUF_SIZE -#define YY_READ_BUF_SIZE 8192 -#undef ECHO -#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) -#undef YY_START_STACK_INCR -#define YY_START_STACK_INCR 25 -#undef YY_DECL_IS_OURS -#define YY_DECL_IS_OURS 1 -#undef YY_DECL -#define YY_DECL int yylex (void) -#undef YY_USER_ACTION -#define YY_USER_ACTION -#undef YY_BREAK -#define YY_BREAK break; -#undef YY_RULE_SETUP -#define YY_RULE_SETUP \ -#undef YY_EXIT_FAILURE -#define YY_EXIT_FAILURE 2 -#undef YYTABLES_NAME -#define YYTABLES_NAME "yytables" -#undef MAXPWD -#define MAXPWD 256 -#undef ALL -#define ALL (E_OPEN|E_CREAT|E_EXEC) -#undef EV_EXIT -#define EV_EXIT 01 /* exit after evaluating tree */ -#undef EV_TESTED -#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ -#undef EV_BACKCMD -#define EV_BACKCMD 04 /* command executing within back quotes */ -#undef CMDTABLESIZE -#define CMDTABLESIZE 31 /* should be prime */ -#undef ARB -#define ARB 1 /* actual size determined at run time */ -#undef NEWARGS -#define NEWARGS 5 -#undef EOF_NLEFT -#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ -#undef _PATH_DEVNULL -#define _PATH_DEVNULL "/dev/null" -#undef PROFILE -#define PROFILE 0 -#undef SIGSSIZE -#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) -#undef MINSIZE -#define MINSIZE 504 /* minimum size of a block */ -#undef DEFINE_OPTIONS -#define DEFINE_OPTIONS -#undef EOFMARKLEN -#define EOFMARKLEN 79 -#undef OPENBRACE -#define OPENBRACE '{' -#undef CLOSEBRACE -#define CLOSEBRACE '}' -#undef EMPTY -#define EMPTY -2 /* marks an unused slot in redirtab */ -#undef S_DFL -#define S_DFL 1 /* default signal handling (SIG_DFL) */ -#undef S_CATCH -#define S_CATCH 2 /* signal is caught */ -#undef S_IGN -#define S_IGN 3 /* signal is ignored (SIG_IGN) */ -#undef S_HARD_IGN -#define S_HARD_IGN 4 /* signal is ignored permenantly */ -#undef S_RESET -#define S_RESET 5 /* temporary - to reset a hard ignored sig */ -#undef OUTBUFSIZ -#define OUTBUFSIZ BUFSIZ -#undef BLOCK_OUT -#define BLOCK_OUT -2 /* output to a fixed block of memory */ -#undef MEM_OUT -#define MEM_OUT -3 /* output to dynamically allocated memory */ -#undef OUTPUT_ERR -#define OUTPUT_ERR 01 /* error occurred on output */ -#undef TEMPSIZE -#define TEMPSIZE 24 -#undef HAVE_VASPRINTF -#define HAVE_VASPRINTF 1 -#undef VTABSIZE -#define VTABSIZE 39 -#undef VTABSIZE -#define VTABSIZE 517 -#undef main -#define main echocmd - - - -extern void rmaliases(void); - -extern int loopnest; /* current loop nesting level */ - -extern void deletefuncs(void); -extern void hash_special_builtins(void); - -struct strpush { - struct strpush *prev; /* preceding string on stack */ - char *prevstring; - int prevnleft; - int prevlleft; - struct alias *ap; /* if push was associated with an alias */ -}; - -struct parsefile { - struct parsefile *prev; /* preceding file on stack */ - int linno; /* current line */ - int fd; /* file descriptor (or -1 if string) */ - int nleft; /* number of chars left in this line */ - int lleft; /* number of chars left in this buffer */ - char *nextc; /* next char in buffer */ - char *buf; /* input buffer */ - struct strpush *strpush; /* for pushing strings at this level */ - struct strpush basestrpush; /* so pushing one is fast */ -}; - -extern int parselleft; /* copy of parsefile->lleft */ -extern struct parsefile basepf; /* top level input file */ -extern char basebuf[BUFSIZ]; /* buffer for top level input file */ - -extern pid_t backgndpid; /* pid of last background process */ -extern int jobctl; - -extern int tokpushback; /* last token pushed back */ -extern int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ - -struct redirtab { - struct redirtab *next; - short renamed[10]; -}; - -extern struct redirtab *redirlist; - -extern char sigmode[NSIG]; /* current value of signal */ - -extern char **environ; - - - -/* - * Initialization code. - */ - -void -init() { - - /* from exec.c: */ - { - hash_special_builtins(); - } - - /* from input.c: */ - { - basepf.nextc = basepf.buf = basebuf; - } - - /* from var.c: */ - { - char **envp; - - initvar(); - for (envp = environ ; *envp ; envp++) { - if (strchr(*envp, '=')) { - setvareq(*envp, VEXPORT|VTEXTFIXED); - } - } - } -} - - - -/* - * This routine is called when an error or an interrupt occurs in an - * interactive shell and control is returned to the main command loop. - */ - -void -reset() { - - /* from eval.c: */ - { - evalskip = 0; - loopnest = 0; - funcnest = 0; - } - - /* from input.c: */ - { - if (exception != EXSHELLPROC) - parselleft = parsenleft = 0; /* clear input buffer */ - popallfiles(); - } - - /* from parser.c: */ - { - tokpushback = 0; - checkkwd = 0; - } - - /* from redir.c: */ - { - while (redirlist) - popredir(); - } - - /* from output.c: */ - { - out1 = &output; - out2 = &errout; - if (memout.buf != NULL) { - ckfree(memout.buf); - memout.buf = NULL; - } - } -} - - - -/* - * This routine is called to initialize the shell to run a shell procedure. - */ - -void -initshellproc() { - - /* from alias.c: */ - { - rmaliases(); - } - - /* from eval.c: */ - { - exitstatus = 0; - } - - /* from exec.c: */ - { - deletefuncs(); - } - - /* from input.c: */ - { - popallfiles(); - } - - /* from jobs.c: */ - { - backgndpid = -1; -#if JOBS - jobctl = 0; -#endif - } - - /* from options.c: */ - { - int i; - - for (i = 0; optlist[i].name; i++) - optlist[i].val = 0; - optschanged(); - - } - - /* from redir.c: */ - { - clearredir(0); - } - - /* from trap.c: */ - { - char *sm; - - clear_traps(0); - for (sm = sigmode ; sm < sigmode + NSIG ; sm++) { - if (*sm == S_IGN) - *sm = S_HARD_IGN; - } - } - - /* from var.c: */ - { - shprocvar(); - } -} diff --git a/sh/init.h b/sh/init.h deleted file mode 100644 index 60d924e9903f78c7fa9cd3e181aae329a07449e1..0000000000000000000000000000000000000000 --- a/sh/init.h +++ /dev/null @@ -1,39 +0,0 @@ -/* $NetBSD: init.h,v 1.10 2003/08/07 09:05:32 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)init.h 8.2 (Berkeley) 5/4/95 - */ - -void init(void); -void reset(void); -void initshellproc(void); diff --git a/sh/input.c b/sh/input.c deleted file mode 100644 index a81fd7b181c2aa225e9d004a42b0795d10f893c4..0000000000000000000000000000000000000000 --- a/sh/input.c +++ /dev/null @@ -1,531 +0,0 @@ -/* $NetBSD: input.c,v 1.39 2003/08/07 09:05:32 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95"; -#else -__RCSID("$NetBSD: input.c,v 1.39 2003/08/07 09:05:32 agc Exp $"); -#endif -#endif /* not lint */ - -#include <stdio.h> /* defines BUFSIZ */ -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#include <string.h> - -/* - * This file implements the input routines used by the parser. - */ - -#include "shell.h" -#include "redir.h" -#include "syntax.h" -#include "input.h" -#include "output.h" -#include "options.h" -#include "memalloc.h" -#include "error.h" -#include "alias.h" -#include "parser.h" -#include "myhistedit.h" - -#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ - -MKINIT -struct strpush { - struct strpush *prev; /* preceding string on stack */ - char *prevstring; - int prevnleft; - int prevlleft; - struct alias *ap; /* if push was associated with an alias */ -}; - -/* - * The parsefile structure pointed to by the global variable parsefile - * contains information about the current file being read. - */ - -MKINIT -struct parsefile { - struct parsefile *prev; /* preceding file on stack */ - int linno; /* current line */ - int fd; /* file descriptor (or -1 if string) */ - int nleft; /* number of chars left in this line */ - int lleft; /* number of chars left in this buffer */ - char *nextc; /* next char in buffer */ - char *buf; /* input buffer */ - struct strpush *strpush; /* for pushing strings at this level */ - struct strpush basestrpush; /* so pushing one is fast */ -}; - - -int plinno = 1; /* input line number */ -int parsenleft; /* copy of parsefile->nleft */ -MKINIT int parselleft; /* copy of parsefile->lleft */ -char *parsenextc; /* copy of parsefile->nextc */ -MKINIT struct parsefile basepf; /* top level input file */ -MKINIT char basebuf[BUFSIZ]; /* buffer for top level input file */ -struct parsefile *parsefile = &basepf; /* current input file */ -int init_editline = 0; /* editline library initialized? */ -int whichprompt; /* 1 == PS1, 2 == PS2 */ - -#if WITH_HISTORY -EditLine *el; /* cookie for editline package */ -#endif - -STATIC void pushfile(void); -static int preadfd(void); - -#ifdef mkinit -INCLUDE <stdio.h> -INCLUDE "input.h" -INCLUDE "error.h" - -INIT { - basepf.nextc = basepf.buf = basebuf; -} - -RESET { - if (exception != EXSHELLPROC) - parselleft = parsenleft = 0; /* clear input buffer */ - popallfiles(); -} - -SHELLPROC { - popallfiles(); -} -#endif - - -/* - * Read a line from the script. - */ - -char * -pfgets(char *line, int len) -{ - char *p = line; - int nleft = len; - int c; - - while (--nleft > 0) { - c = pgetc_macro(); - if (c == PEOF) { - if (p == line) - return NULL; - break; - } - *p++ = c; - if (c == '\n') - break; - } - *p = '\0'; - return line; -} - - - -/* - * Read a character from the script, returning PEOF on end of file. - * Nul characters in the input are silently discarded. - */ - -int -pgetc(void) -{ - return pgetc_macro(); -} - - -static int -preadfd(void) -{ - int nr; - char *buf = parsefile->buf; - parsenextc = buf; - -retry: -#ifdef WITH_HISTORY - if (parsefile->fd == 0 && el) { - static const char *rl_cp; - static int el_len; - - if (rl_cp == NULL) - rl_cp = el_gets(el, &el_len); - if (rl_cp == NULL) - nr = 0; - else { - nr = el_len; - if (nr > BUFSIZ - 8) - nr = BUFSIZ - 8; - memcpy(buf, rl_cp, nr); - if (nr != el_len) { - el_len -= nr; - rl_cp += nr; - } else - rl_cp = 0; - } - - } else -#endif - nr = read(parsefile->fd, buf, BUFSIZ - 8); - - - if (nr <= 0) { - if (nr < 0) { - if (errno == EINTR) - goto retry; - if (parsefile->fd == 0 && errno == EWOULDBLOCK) { - int flags = fcntl(0, F_GETFL, 0); - if (flags >= 0 && flags & O_NONBLOCK) { - flags &=~ O_NONBLOCK; - if (fcntl(0, F_SETFL, flags) >= 0) { - out2str("sh: turning off NDELAY mode\n"); - goto retry; - } - } - } - } - nr = -1; - } - return nr; -} - -/* - * Refill the input buffer and return the next input character: - * - * 1) If a string was pushed back on the input, pop it; - * 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading - * from a string so we can't refill the buffer, return EOF. - * 3) If the is more stuff in this buffer, use it else call read to fill it. - * 4) Process input up to the next newline, deleting nul characters. - */ - -int -preadbuffer(void) -{ - char *p, *q; - int more; - int something; - char savec; - - if (parsefile->strpush) { - popstring(); - if (--parsenleft >= 0) - return (*parsenextc++); - } - if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) - return PEOF; - flushout(&output); - flushout(&errout); - -again: - if (parselleft <= 0) { - if ((parselleft = preadfd()) == -1) { - parselleft = parsenleft = EOF_NLEFT; - return PEOF; - } - } - - q = p = parsenextc; - - /* delete nul characters */ - something = 0; - for (more = 1; more;) { - switch (*p) { - case '\0': - p++; /* Skip nul */ - goto check; - - case '\t': - case ' ': - break; - - case '\n': - parsenleft = q - parsenextc; - more = 0; /* Stop processing here */ - break; - - default: - something = 1; - break; - } - - *q++ = *p++; -check: - if (--parselleft <= 0) { - parsenleft = q - parsenextc - 1; - if (parsenleft < 0) - goto again; - *q = '\0'; - more = 0; - } - } - - savec = *q; - *q = '\0'; - -#ifdef WITH_HISTORY - if (parsefile->fd == 0 && hist && something) { - HistEvent he; - INTOFF; - history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND, - parsenextc); - INTON; - } -#endif - - if (vflag) { - out2str(parsenextc); - flushout(out2); - } - - *q = savec; - - return *parsenextc++; -} - -/* - * Undo the last call to pgetc. Only one character may be pushed back. - * PEOF may be pushed back. - */ - -void -pungetc(void) -{ - parsenleft++; - parsenextc--; -} - -/* - * Push a string back onto the input at this current parsefile level. - * We handle aliases this way. - */ -void -pushstring(char *s, int len, void *ap) -{ - struct strpush *sp; - - INTOFF; -/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ - if (parsefile->strpush) { - sp = ckmalloc(sizeof (struct strpush)); - sp->prev = parsefile->strpush; - parsefile->strpush = sp; - } else - sp = parsefile->strpush = &(parsefile->basestrpush); - sp->prevstring = parsenextc; - sp->prevnleft = parsenleft; - sp->prevlleft = parselleft; - sp->ap = (struct alias *)ap; - if (ap) - ((struct alias *)ap)->flag |= ALIASINUSE; - parsenextc = s; - parsenleft = len; - INTON; -} - -void -popstring(void) -{ - struct strpush *sp = parsefile->strpush; - - INTOFF; - parsenextc = sp->prevstring; - parsenleft = sp->prevnleft; - parselleft = sp->prevlleft; -/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ - if (sp->ap) - sp->ap->flag &= ~ALIASINUSE; - parsefile->strpush = sp->prev; - if (sp != &(parsefile->basestrpush)) - ckfree(sp); - INTON; -} - -/* - * Set the input to take input from a file. If push is set, push the - * old input onto the stack first. - */ - -void -setinputfile(const char *fname, int push) -{ - int fd; - int fd2; - - INTOFF; - if ((fd = open(fname, O_RDONLY)) < 0) - error("Can't open %s", fname); - if (fd < 10) { - fd2 = copyfd(fd, 10); - close(fd); - if (fd2 < 0) - error("Out of file descriptors"); - fd = fd2; - } - setinputfd(fd, push); - INTON; -} - - -/* - * Like setinputfile, but takes an open file descriptor. Call this with - * interrupts off. - */ - -void -setinputfd(int fd, int push) -{ - (void) fcntl(fd, F_SETFD, FD_CLOEXEC); - if (push) { - pushfile(); - parsefile->buf = ckmalloc(BUFSIZ); - } - if (parsefile->fd > 0) - close(parsefile->fd); - parsefile->fd = fd; - if (parsefile->buf == NULL) - parsefile->buf = ckmalloc(BUFSIZ); - parselleft = parsenleft = 0; - plinno = 1; -} - - -/* - * Like setinputfile, but takes input from a string. - */ - -void -setinputstring(char *string, int push) -{ - INTOFF; - if (push) - pushfile(); - parsenextc = string; - parselleft = parsenleft = strlen(string); - parsefile->buf = NULL; - plinno = 1; - INTON; -} - - - -/* - * To handle the "." command, a stack of input files is used. Pushfile - * adds a new entry to the stack and popfile restores the previous level. - */ - -STATIC void -pushfile(void) -{ - struct parsefile *pf; - - parsefile->nleft = parsenleft; - parsefile->lleft = parselleft; - parsefile->nextc = parsenextc; - parsefile->linno = plinno; - pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile)); - pf->prev = parsefile; - pf->fd = -1; - pf->strpush = NULL; - pf->basestrpush.prev = NULL; - parsefile = pf; -} - - -void -popfile(void) -{ - struct parsefile *pf = parsefile; - - INTOFF; - if (pf->fd >= 0) - close(pf->fd); - if (pf->buf) - ckfree(pf->buf); - while (pf->strpush) - popstring(); - parsefile = pf->prev; - ckfree(pf); - parsenleft = parsefile->nleft; - parselleft = parsefile->lleft; - parsenextc = parsefile->nextc; - plinno = parsefile->linno; - INTON; -} - - -/* - * Return to top level. - */ - -void -popallfiles(void) -{ - while (parsefile != &basepf) - popfile(); -} - - - -/* - * Close the file(s) that the shell is reading commands from. Called - * after a fork is done. - * - * Takes one arg, vfork, which tells it to not modify its global vars - * as it is still running in the parent. - * - * This code is (probably) unnecessary as the 'close on exec' flag is - * set and should be enough. In the vfork case it is definitely wrong - * to close the fds as another fork() may be done later to feed data - * from a 'here' document into a pipe and we don't want to close the - * pipe! - */ - -void -closescript(int vforked) -{ - if (vforked) - return; - popallfiles(); - if (parsefile->fd > 0) { - close(parsefile->fd); - parsefile->fd = 0; - } -} diff --git a/sh/input.h b/sh/input.h deleted file mode 100644 index a9d3a12b429d1abbe192907068efe9dee54532c8..0000000000000000000000000000000000000000 --- a/sh/input.h +++ /dev/null @@ -1,62 +0,0 @@ -/* $NetBSD: input.h,v 1.15 2003/08/07 09:05:33 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)input.h 8.2 (Berkeley) 5/4/95 - */ - -/* PEOF (the end of file marker) is defined in syntax.h */ - -/* - * The input line number. Input.c just defines this variable, and saves - * and restores it when files are pushed and popped. The user of this - * package must set its value. - */ -extern int plinno; -extern int parsenleft; /* number of characters left in input buffer */ -extern char *parsenextc; /* next character in input buffer */ -extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */ - -char *pfgets(char *, int); -int pgetc(void); -int preadbuffer(void); -void pungetc(void); -void pushstring(char *, int, void *); -void popstring(void); -void setinputfile(const char *, int); -void setinputfd(int, int); -void setinputstring(char *, int); -void popfile(void); -void popallfiles(void); -void closescript(int); - -#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) diff --git a/sh/jobs.c b/sh/jobs.c deleted file mode 100644 index b9460b0396ff894227652af3c422681a0b9e1b0d..0000000000000000000000000000000000000000 --- a/sh/jobs.c +++ /dev/null @@ -1,1487 +0,0 @@ -/* $NetBSD: jobs.c,v 1.62 2003/12/18 00:56:05 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: jobs.c,v 1.62 2003/12/18 00:56:05 christos Exp $"); -#endif -#endif /* not lint */ - -#include <fcntl.h> -#include <signal.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> -#define _PATH_DEVNULL "/dev/null" -#include <sys/types.h> -#include <sys/param.h> -#ifdef BSD -#include <sys/wait.h> -#include <sys/time.h> -#include <sys/resource.h> -#endif -#include <sys/wait.h> -#define killpg(s,i) kill(-(s),i) -#include <sys/ioctl.h> - -#include "shell.h" -#if JOBS -#if OLD_TTY_DRIVER -#include "sgtty.h" -#else -#include <termios.h> -#endif -#undef CEOF /* syntax.h redefines this */ -#endif -#include "redir.h" -#include "show.h" -#include "main.h" -#include "parser.h" -#include "nodes.h" -#include "jobs.h" -#include "options.h" -#include "trap.h" -#include "syntax.h" -#include "input.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "mystring.h" - -// Use of process groups is disabled to allow adb shell children to terminate when the shell dies -#define USE_PROCESS_GROUPS - - -static struct job *jobtab; /* array of jobs */ -static int njobs; /* size of array */ -static int jobs_invalid; /* set in child */ -MKINIT pid_t backgndpid = -1; /* pid of last background process */ -#if JOBS -int initialpgrp; /* pgrp of shell on invocation */ -static int curjob = -1; /* current job */ -#endif -static int ttyfd = -1; - -STATIC void restartjob(struct job *); -STATIC void freejob(struct job *); -STATIC struct job *getjob(const char *, int); -STATIC int dowait(int, struct job *); -STATIC int onsigchild(void); -STATIC int waitproc(int, struct job *, int *); -STATIC void cmdtxt(union node *); -STATIC void cmdlist(union node *, int); -STATIC void cmdputs(const char *); - -#ifdef OLD_TTY_DRIVER -static pid_t tcgetpgrp(int fd); -static int tcsetpgrp(int fd, pid_t pgrp); - -static pid_t -tcgetpgrp(int fd) -{ - pid_t pgrp; - if (ioctl(fd, TIOCGPGRP, (char *)&pgrp) == -1) - return -1; - else - return pgrp; -} - -static int -tcsetpgrp(int fd, pid_tpgrp) -{ - return ioctl(fd, TIOCSPGRP, (char *)&pgrp); -} -#endif - -/* - * Turn job control on and off. - * - * Note: This code assumes that the third arg to ioctl is a character - * pointer, which is true on Berkeley systems but not System V. Since - * System V doesn't have job control yet, this isn't a problem now. - */ - -MKINIT int jobctl; - -void -setjobctl(int on) -{ -#ifdef OLD_TTY_DRIVER - int ldisc; -#endif - - if (on == jobctl || rootshell == 0) - return; - if (on) { -#if defined(FIOCLEX) || defined(FD_CLOEXEC) - int err; - int i; - if (ttyfd != -1) - close(ttyfd); - if ((ttyfd = open("/dev/tty", O_RDWR)) == -1) { - for (i = 0; i < 3; i++) { - if (isatty(i) && (ttyfd = dup(i)) != -1) - break; - } - if (i == 3) - goto out; - } - /* Move to a high fd */ - for (i = 10; i > 2; i--) { - if ((err = fcntl(ttyfd, F_DUPFD, (1 << i) - 1)) != -1) - break; - } - if (err != -1) { - close(ttyfd); - ttyfd = err; - } -#ifdef FIOCLEX - err = ioctl(ttyfd, FIOCLEX, 0); -#elif FD_CLOEXEC - err = fcntl(ttyfd, F_SETFD, - fcntl(ttyfd, F_GETFD, 0) | FD_CLOEXEC); -#endif - if (err == -1) { - close(ttyfd); - ttyfd = -1; - goto out; - } -#else - out2str("sh: Need FIOCLEX or FD_CLOEXEC to support job control"); - goto out; -#endif - do { /* while we are in the background */ - if ((initialpgrp = tcgetpgrp(ttyfd)) < 0) { -out: - out2str("sh: can't access tty; job control turned off\n"); - mflag = 0; - return; - } - if (initialpgrp == -1) - initialpgrp = getpgrp(); - else if (initialpgrp != getpgrp()) { - killpg(0, SIGTTIN); - continue; - } - } while (0); - -#ifdef OLD_TTY_DRIVER - if (ioctl(ttyfd, TIOCGETD, (char *)&ldisc) < 0 - || ldisc != NTTYDISC) { - out2str("sh: need new tty driver to run job control; job control turned off\n"); - mflag = 0; - return; - } -#endif - setsignal(SIGTSTP, 0); - setsignal(SIGTTOU, 0); - setsignal(SIGTTIN, 0); -#ifdef USE_PROCESS_GROUPS - if (getpgid(0) != rootpid && setpgid(0, rootpid) == -1) - error("Cannot set process group (%s) at %d", - strerror(errno), __LINE__); - if (tcsetpgrp(ttyfd, rootpid) == -1) - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); -#endif - } else { /* turning job control off */ -#ifdef USE_PROCESS_GROUPS - if (getpgid(0) != initialpgrp && setpgid(0, initialpgrp) == -1) - error("Cannot set process group (%s) at %d", - strerror(errno), __LINE__); - if (tcsetpgrp(ttyfd, initialpgrp) == -1) - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); -#endif - close(ttyfd); - ttyfd = -1; - setsignal(SIGTSTP, 0); - setsignal(SIGTTOU, 0); - setsignal(SIGTTIN, 0); - } - jobctl = on; -} - - -#ifdef mkinit -INCLUDE <stdlib.h> - -SHELLPROC { - backgndpid = -1; -#if JOBS - jobctl = 0; -#endif -} - -#endif - - - -#if JOBS -int -fgcmd(int argc, char **argv) -{ - struct job *jp; - int i; - int status; - - nextopt(""); - jp = getjob(*argptr, 0); - if (jp->jobctl == 0) - error("job not created under job control"); - out1fmt("%s", jp->ps[0].cmd); - for (i = 1; i < jp->nprocs; i++) - out1fmt(" | %s", jp->ps[i].cmd ); - out1c('\n'); - flushall(); - - for (i = 0; i < jp->nprocs; i++) - if (tcsetpgrp(ttyfd, jp->ps[i].pid) != -1) - break; - - if (i >= jp->nprocs) { - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); - } - restartjob(jp); - INTOFF; - status = waitforjob(jp); - INTON; - return status; -} - -static void -set_curjob(struct job *jp, int mode) -{ - struct job *jp1, *jp2; - int i, ji; - - ji = jp - jobtab; - - /* first remove from list */ - if (ji == curjob) - curjob = jp->prev_job; - else { - for (i = 0; i < njobs; i++) { - if (jobtab[i].prev_job != ji) - continue; - jobtab[i].prev_job = jp->prev_job; - break; - } - } - - /* Then re-insert in correct position */ - switch (mode) { - case 0: /* job being deleted */ - jp->prev_job = -1; - break; - case 1: /* newly created job or backgrounded job, - put after all stopped jobs. */ - if (curjob != -1 && jobtab[curjob].state == JOBSTOPPED) { - for (jp1 = jobtab + curjob; ; jp1 = jp2) { - if (jp1->prev_job == -1) - break; - jp2 = jobtab + jp1->prev_job; - if (jp2->state != JOBSTOPPED) - break; - } - jp->prev_job = jp1->prev_job; - jp1->prev_job = ji; - break; - } - /* FALLTHROUGH */ - case 2: /* newly stopped job - becomes curjob */ - jp->prev_job = curjob; - curjob = ji; - break; - } -} - -int -bgcmd(int argc, char **argv) -{ - struct job *jp; - int i; - - nextopt(""); - do { - jp = getjob(*argptr, 0); - if (jp->jobctl == 0) - error("job not created under job control"); - set_curjob(jp, 1); - out1fmt("[%ld] %s", (long)(jp - jobtab + 1), jp->ps[0].cmd); - for (i = 1; i < jp->nprocs; i++) - out1fmt(" | %s", jp->ps[i].cmd ); - out1c('\n'); - flushall(); - restartjob(jp); - } while (*argptr && *++argptr); - return 0; -} - - -STATIC void -restartjob(struct job *jp) -{ - struct procstat *ps; - int i; - - if (jp->state == JOBDONE) - return; - INTOFF; - for (i = 0; i < jp->nprocs; i++) - if (killpg(jp->ps[i].pid, SIGCONT) != -1) - break; - if (i >= jp->nprocs) - error("Cannot continue job (%s)", strerror(errno)); - for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { - if (WIFSTOPPED(ps->status)) { - ps->status = -1; - jp->state = JOBRUNNING; - } - } - INTON; -} -#endif - -static void -showjob(struct output *out, struct job *jp, int mode) -{ - int procno; - int st; - struct procstat *ps; - int col; - char s[64]; - -#if JOBS - if (mode & SHOW_PGID) { - /* just output process (group) id of pipeline */ - outfmt(out, "%ld\n", (long)jp->ps->pid); - return; - } -#endif - - procno = jp->nprocs; - if (!procno) - return; - - if (mode & SHOW_PID) - mode |= SHOW_MULTILINE; - - if ((procno > 1 && !(mode & SHOW_MULTILINE)) - || (mode & SHOW_SIGNALLED)) { - /* See if we have more than one status to report */ - ps = jp->ps; - st = ps->status; - do { - int st1 = ps->status; - if (st1 != st) - /* yes - need multi-line output */ - mode |= SHOW_MULTILINE; - if (st1 == -1 || !(mode & SHOW_SIGNALLED) || WIFEXITED(st1)) - continue; - if (WIFSTOPPED(st1) || ((st1 = WTERMSIG(st1) & 0x7f) - && st1 != SIGINT && st1 != SIGPIPE)) - mode |= SHOW_ISSIG; - - } while (ps++, --procno); - procno = jp->nprocs; - } - - if (mode & SHOW_SIGNALLED && !(mode & SHOW_ISSIG)) { - if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) { - TRACE(("showjob: freeing job %d\n", jp - jobtab + 1)); - freejob(jp); - } - return; - } - - for (ps = jp->ps; --procno >= 0; ps++) { /* for each process */ - if (ps == jp->ps) - fmtstr(s, 16, "[%ld] %c ", - (long)(jp - jobtab + 1), -#if JOBS - jp == jobtab + curjob ? '+' : - curjob != -1 && jp == jobtab + - jobtab[curjob].prev_job ? '-' : -#endif - ' '); - else - fmtstr(s, 16, " " ); - col = strlen(s); - if (mode & SHOW_PID) { - fmtstr(s + col, 16, "%ld ", (long)ps->pid); - col += strlen(s + col); - } - if (ps->status == -1) { - scopy("Running", s + col); - } else if (WIFEXITED(ps->status)) { - st = WEXITSTATUS(ps->status); - if (st) - fmtstr(s + col, 16, "Done(%d)", st); - else - fmtstr(s + col, 16, "Done"); - } else { -#if JOBS - if (WIFSTOPPED(ps->status)) - st = WSTOPSIG(ps->status); - else /* WIFSIGNALED(ps->status) */ -#endif - st = WTERMSIG(ps->status); - st &= 0x7f; - if (st < NSIG && sys_siglist[st]) - scopyn(sys_siglist[st], s + col, 32); - else - fmtstr(s + col, 16, "Signal %d", st); - if (WCOREDUMP(ps->status)) { - col += strlen(s + col); - scopyn(" (core dumped)", s + col, 64 - col); - } - } - col += strlen(s + col); - outstr(s, out); - do { - outc(' ', out); - col++; - } while (col < 30); - outstr(ps->cmd, out); - if (mode & SHOW_MULTILINE) { - if (procno > 0) { - outc(' ', out); - outc('|', out); - } - } else { - while (--procno >= 0) - outfmt(out, " | %s", (++ps)->cmd ); - } - outc('\n', out); - } - flushout(out); - jp->changed = 0; - if (jp->state == JOBDONE && !(mode & SHOW_NO_FREE)) - freejob(jp); -} - - -int -jobscmd(int argc, char **argv) -{ - int mode, m; - int sv = jobs_invalid; - - jobs_invalid = 0; - mode = 0; - while ((m = nextopt("lp"))) - if (m == 'l') - mode = SHOW_PID; - else - mode = SHOW_PGID; - if (*argptr) - do - showjob(out1, getjob(*argptr,0), mode); - while (*++argptr); - else - showjobs(out1, mode); - jobs_invalid = sv; - return 0; -} - - -/* - * Print a list of jobs. If "change" is nonzero, only print jobs whose - * statuses have changed since the last call to showjobs. - * - * If the shell is interrupted in the process of creating a job, the - * result may be a job structure containing zero processes. Such structures - * will be freed here. - */ - -void -showjobs(struct output *out, int mode) -{ - int jobno; - struct job *jp; - int silent = 0, gotpid; - - TRACE(("showjobs(%x) called\n", mode)); - - /* If not even one one job changed, there is nothing to do */ - gotpid = dowait(0, NULL); - while (dowait(0, NULL) > 0) - continue; -#ifdef JOBS - /* - * Check if we are not in our foreground group, and if not - * put us in it. - */ - if (mflag && gotpid != -1 && tcgetpgrp(ttyfd) != getpid()) { - if (tcsetpgrp(ttyfd, getpid()) == -1) - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); - TRACE(("repaired tty process group\n")); - silent = 1; - } -#endif - if (jobs_invalid) - return; - - for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { - if (!jp->used) - continue; - if (jp->nprocs == 0) { - freejob(jp); - continue; - } - if ((mode & SHOW_CHANGED) && !jp->changed) - continue; - if (silent && jp->changed) { - jp->changed = 0; - continue; - } - showjob(out, jp, mode); - } -} - -/* - * Mark a job structure as unused. - */ - -STATIC void -freejob(struct job *jp) -{ - INTOFF; - if (jp->ps != &jp->ps0) { - ckfree(jp->ps); - jp->ps = &jp->ps0; - } - jp->nprocs = 0; - jp->used = 0; -#if JOBS - set_curjob(jp, 0); -#endif - INTON; -} - - - -int -waitcmd(int argc, char **argv) -{ - struct job *job; - int status, retval = 127; - struct job *jp; - - nextopt(""); - - if (!*argptr) { - /* wait for all jobs */ - jp = jobtab; - if (jobs_invalid) - return 0; - for (;;) { - if (jp >= jobtab + njobs) { - /* no running procs */ - return 0; - } - if (!jp->used || jp->state != JOBRUNNING) { - jp++; - continue; - } - if (dowait(1, (struct job *)NULL) == -1) - return 128 + SIGINT; - jp = jobtab; - } - } - - for (; *argptr; argptr++) { - job = getjob(*argptr, 1); - if (!job) { - retval = 127; - continue; - } - /* loop until process terminated or stopped */ - while (job->state == JOBRUNNING) { - if (dowait(1, (struct job *)NULL) == -1) - return 128 + SIGINT; - } - status = job->ps[job->nprocs].status; - if (WIFEXITED(status)) - retval = WEXITSTATUS(status); -#if JOBS - else if (WIFSTOPPED(status)) - retval = WSTOPSIG(status) + 128; -#endif - else { - /* XXX: limits number of signals */ - retval = WTERMSIG(status) + 128; - } - if (!iflag) - freejob(job); - } - return retval; -} - - - -int -jobidcmd(int argc, char **argv) -{ - struct job *jp; - int i; - - nextopt(""); - jp = getjob(*argptr, 0); - for (i = 0 ; i < jp->nprocs ; ) { - out1fmt("%ld", (long)jp->ps[i].pid); - out1c(++i < jp->nprocs ? ' ' : '\n'); - } - return 0; -} - -int -getjobpgrp(const char *name) -{ - struct job *jp; - - jp = getjob(name, 1); - if (jp == 0) - return 0; - return -jp->ps[0].pid; -} - -/* - * Convert a job name to a job structure. - */ - -STATIC struct job * -getjob(const char *name, int noerror) -{ - int jobno = -1; - struct job *jp; - int pid; - int i; - const char *err_msg = "No such job: %s"; - - if (name == NULL) { -#if JOBS - jobno = curjob; -#endif - err_msg = "No current job"; - } else if (name[0] == '%') { - if (is_number(name + 1)) { - jobno = number(name + 1) - 1; - } else if (!name[2]) { - switch (name[1]) { -#if JOBS - case 0: - case '+': - case '%': - jobno = curjob; - err_msg = "No current job"; - break; - case '-': - jobno = curjob; - if (jobno != -1) - jobno = jobtab[jobno].prev_job; - err_msg = "No previous job"; - break; -#endif - default: - goto check_pattern; - } - } else { - struct job *found; - check_pattern: - found = NULL; - for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { - if (!jp->used || jp->nprocs <= 0) - continue; - if ((name[1] == '?' - && strstr(jp->ps[0].cmd, name + 2)) - || prefix(name + 1, jp->ps[0].cmd)) { - if (found) { - err_msg = "%s: ambiguous"; - found = 0; - break; - } - found = jp; - } - } - if (found) - return found; - } - - } else if (is_number(name)) { - pid = number(name); - for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { - if (jp->used && jp->nprocs > 0 - && jp->ps[jp->nprocs - 1].pid == pid) - return jp; - } - } - - if (!jobs_invalid && jobno >= 0 && jobno < njobs) { - jp = jobtab + jobno; - if (jp->used) - return jp; - } - if (!noerror) - error(err_msg, name); - return 0; -} - - - -/* - * Return a new job structure, - */ - -struct job * -makejob(union node *node, int nprocs) -{ - int i; - struct job *jp; - - if (jobs_invalid) { - for (i = njobs, jp = jobtab ; --i >= 0 ; jp++) { - if (jp->used) - freejob(jp); - } - jobs_invalid = 0; - } - - for (i = njobs, jp = jobtab ; ; jp++) { - if (--i < 0) { - INTOFF; - if (njobs == 0) { - jobtab = ckmalloc(4 * sizeof jobtab[0]); - } else { - jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); - memcpy(jp, jobtab, njobs * sizeof jp[0]); - /* Relocate `ps' pointers */ - for (i = 0; i < njobs; i++) - if (jp[i].ps == &jobtab[i].ps0) - jp[i].ps = &jp[i].ps0; - ckfree(jobtab); - jobtab = jp; - } - jp = jobtab + njobs; - for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0); - INTON; - break; - } - if (jp->used == 0) - break; - } - INTOFF; - jp->state = JOBRUNNING; - jp->used = 1; - jp->changed = 0; - jp->nprocs = 0; -#if JOBS - jp->jobctl = jobctl; - set_curjob(jp, 1); -#endif - if (nprocs > 1) { - jp->ps = ckmalloc(nprocs * sizeof (struct procstat)); - } else { - jp->ps = &jp->ps0; - } - INTON; - TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, - jp - jobtab + 1)); - return jp; -} - - -/* - * Fork off a subshell. If we are doing job control, give the subshell its - * own process group. Jp is a job structure that the job is to be added to. - * N is the command that will be evaluated by the child. Both jp and n may - * be NULL. The mode parameter can be one of the following: - * FORK_FG - Fork off a foreground process. - * FORK_BG - Fork off a background process. - * FORK_NOJOB - Like FORK_FG, but don't give the process its own - * process group even if job control is on. - * - * When job control is turned off, background processes have their standard - * input redirected to /dev/null (except for the second and later processes - * in a pipeline). - */ - -int -forkshell(struct job *jp, union node *n, int mode) -{ - int pid; - - TRACE(("forkshell(%%%d, %p, %d) called\n", jp - jobtab, n, mode)); - switch ((pid = fork())) { - case -1: - TRACE(("Fork failed, errno=%d\n", errno)); - INTON; - error("Cannot fork"); - break; - case 0: - forkchild(jp, n, mode, 0); - return 0; - default: - return forkparent(jp, n, mode, pid); - } -} - -int -forkparent(struct job *jp, union node *n, int mode, pid_t pid) -{ - int pgrp; - - if (rootshell && mode != FORK_NOJOB && mflag) { - if (jp == NULL || jp->nprocs == 0) - pgrp = pid; - else - pgrp = jp->ps[0].pid; -#ifdef USE_PROCESS_GROUPS - /* This can fail because we are doing it in the child also */ - (void)setpgid(pid, pgrp); -#endif - } - if (mode == FORK_BG) - backgndpid = pid; /* set $! */ - if (jp) { - struct procstat *ps = &jp->ps[jp->nprocs++]; - ps->pid = pid; - ps->status = -1; - ps->cmd[0] = 0; - if (/* iflag && rootshell && */ n) - commandtext(ps, n); - } - TRACE(("In parent shell: child = %d\n", pid)); - return pid; -} - -void -forkchild(struct job *jp, union node *n, int mode, int vforked) -{ - int wasroot; - int pgrp; - const char *devnull = _PATH_DEVNULL; - const char *nullerr = "Can't open %s"; - - wasroot = rootshell; - TRACE(("Child shell %d\n", getpid())); - if (!vforked) - rootshell = 0; - - closescript(vforked); - clear_traps(vforked); -#if JOBS - if (!vforked) - jobctl = 0; /* do job control only in root shell */ - if (wasroot && mode != FORK_NOJOB && mflag) { - if (jp == NULL || jp->nprocs == 0) - pgrp = getpid(); - else - pgrp = jp->ps[0].pid; -#ifdef USE_PROCESS_GROUPS - /* This can fail because we are doing it in the parent also */ - (void)setpgid(0, pgrp); - if (mode == FORK_FG) { - if (tcsetpgrp(ttyfd, pgrp) == -1) - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); - } -#endif - setsignal(SIGTSTP, vforked); - setsignal(SIGTTOU, vforked); - } else if (mode == FORK_BG) { - ignoresig(SIGINT, vforked); - ignoresig(SIGQUIT, vforked); - if ((jp == NULL || jp->nprocs == 0) && - ! fd0_redirected_p ()) { - close(0); - if (open(devnull, O_RDONLY) != 0) - error(nullerr, devnull); - } - } -#else - if (mode == FORK_BG) { - ignoresig(SIGINT, vforked); - ignoresig(SIGQUIT, vforked); - if ((jp == NULL || jp->nprocs == 0) && - ! fd0_redirected_p ()) { - close(0); - if (open(devnull, O_RDONLY) != 0) - error(nullerr, devnull); - } - } -#endif - if (wasroot && iflag) { - setsignal(SIGINT, vforked); - setsignal(SIGQUIT, vforked); - setsignal(SIGTERM, vforked); - } - - if (!vforked) - jobs_invalid = 1; -} - -/* - * Wait for job to finish. - * - * Under job control we have the problem that while a child process is - * running interrupts generated by the user are sent to the child but not - * to the shell. This means that an infinite loop started by an inter- - * active user may be hard to kill. With job control turned off, an - * interactive user may place an interactive program inside a loop. If - * the interactive program catches interrupts, the user doesn't want - * these interrupts to also abort the loop. The approach we take here - * is to have the shell ignore interrupt signals while waiting for a - * forground process to terminate, and then send itself an interrupt - * signal if the child process was terminated by an interrupt signal. - * Unfortunately, some programs want to do a bit of cleanup and then - * exit on interrupt; unless these processes terminate themselves by - * sending a signal to themselves (instead of calling exit) they will - * confuse this approach. - */ - -int -waitforjob(struct job *jp) -{ -#if JOBS - int mypgrp = getpgrp(); -#endif - int status; - int st; - - INTOFF; - TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1)); - while (jp->state == JOBRUNNING) { - dowait(1, jp); - } -#if JOBS - if (jp->jobctl) { - if (tcsetpgrp(ttyfd, mypgrp) == -1) - error("Cannot set tty process group (%s) at %d", - strerror(errno), __LINE__); - } - if (jp->state == JOBSTOPPED && curjob != jp - jobtab) - set_curjob(jp, 2); -#endif - status = jp->ps[jp->nprocs - 1].status; - /* convert to 8 bits */ - if (WIFEXITED(status)) - st = WEXITSTATUS(status); -#if JOBS - else if (WIFSTOPPED(status)) - st = WSTOPSIG(status) + 128; -#endif - else - st = WTERMSIG(status) + 128; - TRACE(("waitforjob: job %d, nproc %d, status %x, st %x\n", - jp - jobtab + 1, jp->nprocs, status, st )); -#if JOBS - if (jp->jobctl) { - /* - * This is truly gross. - * If we're doing job control, then we did a TIOCSPGRP which - * caused us (the shell) to no longer be in the controlling - * session -- so we wouldn't have seen any ^C/SIGINT. So, we - * intuit from the subprocess exit status whether a SIGINT - * occurred, and if so interrupt ourselves. Yuck. - mycroft - */ - if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) - raise(SIGINT); - } -#endif - if (! JOBS || jp->state == JOBDONE) - freejob(jp); - INTON; - return st; -} - - - -/* - * Wait for a process to terminate. - */ - -STATIC int -dowait(int block, struct job *job) -{ - int pid; - int status; - struct procstat *sp; - struct job *jp; - struct job *thisjob; - int done; - int stopped; - extern volatile char gotsig[]; - - TRACE(("dowait(%d) called\n", block)); - do { - pid = waitproc(block, job, &status); - TRACE(("wait returns pid %d, status %d\n", pid, status)); - } while (pid == -1 && errno == EINTR && gotsig[SIGINT - 1] == 0); - if (pid <= 0) - return pid; - INTOFF; - thisjob = NULL; - for (jp = jobtab ; jp < jobtab + njobs ; jp++) { - if (jp->used) { - done = 1; - stopped = 1; - for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { - if (sp->pid == -1) - continue; - if (sp->pid == pid) { - TRACE(("Job %d: changing status of proc %d from 0x%x to 0x%x\n", jp - jobtab + 1, pid, sp->status, status)); - sp->status = status; - thisjob = jp; - } - if (sp->status == -1) - stopped = 0; - else if (WIFSTOPPED(sp->status)) - done = 0; - } - if (stopped) { /* stopped or done */ - int state = done ? JOBDONE : JOBSTOPPED; - if (jp->state != state) { - TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state)); - jp->state = state; -#if JOBS - if (done) - set_curjob(jp, 0); -#endif - } - } - } - } - - if (thisjob && thisjob->state != JOBRUNNING) { - int mode = 0; - if (!rootshell || !iflag) - mode = SHOW_SIGNALLED; - if (job == thisjob) - mode = SHOW_SIGNALLED | SHOW_NO_FREE; - if (mode) - showjob(out2, thisjob, mode); - else { - TRACE(("Not printing status, rootshell=%d, job=%p\n", - rootshell, job)); - thisjob->changed = 1; - } - } - - INTON; - return pid; -} - - - -/* - * Do a wait system call. If job control is compiled in, we accept - * stopped processes. If block is zero, we return a value of zero - * rather than blocking. - * - * System V doesn't have a non-blocking wait system call. It does - * have a SIGCLD signal that is sent to a process when one of it's - * children dies. The obvious way to use SIGCLD would be to install - * a handler for SIGCLD which simply bumped a counter when a SIGCLD - * was received, and have waitproc bump another counter when it got - * the status of a process. Waitproc would then know that a wait - * system call would not block if the two counters were different. - * This approach doesn't work because if a process has children that - * have not been waited for, System V will send it a SIGCLD when it - * installs a signal handler for SIGCLD. What this means is that when - * a child exits, the shell will be sent SIGCLD signals continuously - * until is runs out of stack space, unless it does a wait call before - * restoring the signal handler. The code below takes advantage of - * this (mis)feature by installing a signal handler for SIGCLD and - * then checking to see whether it was called. If there are any - * children to be waited for, it will be. - * - * If neither SYSV nor BSD is defined, we don't implement nonblocking - * waits at all. In this case, the user will not be informed when - * a background process until the next time she runs a real program - * (as opposed to running a builtin command or just typing return), - * and the jobs command may give out of date information. - */ - -#ifdef SYSV -STATIC int gotsigchild; - -STATIC int onsigchild() { - gotsigchild = 1; -} -#endif - - -STATIC int -waitproc(int block, struct job *jp, int *status) -{ -#ifdef BSD - int flags = 0; - -#if JOBS - if (jp != NULL && jp->jobctl) - flags |= WUNTRACED; -#endif - if (block == 0) - flags |= WNOHANG; - return wait3(status, flags, (struct rusage *)NULL); -#else -#ifdef SYSV - int (*save)(); - - if (block == 0) { - gotsigchild = 0; - save = signal(SIGCLD, onsigchild); - signal(SIGCLD, save); - if (gotsigchild == 0) - return 0; - } - return wait(status); -#else - if (block == 0) - return 0; - return wait(status); -#endif -#endif -} - -/* - * return 1 if there are stopped jobs, otherwise 0 - */ -int job_warning = 0; -int -stoppedjobs(void) -{ - int jobno; - struct job *jp; - - if (job_warning || jobs_invalid) - return (0); - for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { - if (jp->used == 0) - continue; - if (jp->state == JOBSTOPPED) { - out2str("You have stopped jobs.\n"); - job_warning = 2; - return (1); - } - } - - return (0); -} - -/* - * Return a string identifying a command (to be printed by the - * jobs command). - */ - -STATIC char *cmdnextc; -STATIC int cmdnleft; - -void -commandtext(struct procstat *ps, union node *n) -{ - int len; - - cmdnextc = ps->cmd; - if (iflag || mflag || sizeof ps->cmd < 100) - len = sizeof(ps->cmd); - else - len = sizeof(ps->cmd) / 10; - cmdnleft = len; - cmdtxt(n); - if (cmdnleft <= 0) { - char *p = ps->cmd + len - 4; - p[0] = '.'; - p[1] = '.'; - p[2] = '.'; - p[3] = 0; - } else - *cmdnextc = '\0'; - TRACE(("commandtext: ps->cmd %x, end %x, left %d\n\t\"%s\"\n", - ps->cmd, cmdnextc, cmdnleft, ps->cmd)); -} - - -STATIC void -cmdtxt(union node *n) -{ - union node *np; - struct nodelist *lp; - const char *p; - int i; - char s[2]; - - if (n == NULL || cmdnleft <= 0) - return; - switch (n->type) { - case NSEMI: - cmdtxt(n->nbinary.ch1); - cmdputs("; "); - cmdtxt(n->nbinary.ch2); - break; - case NAND: - cmdtxt(n->nbinary.ch1); - cmdputs(" && "); - cmdtxt(n->nbinary.ch2); - break; - case NOR: - cmdtxt(n->nbinary.ch1); - cmdputs(" || "); - cmdtxt(n->nbinary.ch2); - break; - case NPIPE: - for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { - cmdtxt(lp->n); - if (lp->next) - cmdputs(" | "); - } - break; - case NSUBSHELL: - cmdputs("("); - cmdtxt(n->nredir.n); - cmdputs(")"); - break; - case NREDIR: - case NBACKGND: - cmdtxt(n->nredir.n); - break; - case NIF: - cmdputs("if "); - cmdtxt(n->nif.test); - cmdputs("; then "); - cmdtxt(n->nif.ifpart); - if (n->nif.elsepart) { - cmdputs("; else "); - cmdtxt(n->nif.elsepart); - } - cmdputs("; fi"); - break; - case NWHILE: - cmdputs("while "); - goto until; - case NUNTIL: - cmdputs("until "); -until: - cmdtxt(n->nbinary.ch1); - cmdputs("; do "); - cmdtxt(n->nbinary.ch2); - cmdputs("; done"); - break; - case NFOR: - cmdputs("for "); - cmdputs(n->nfor.var); - cmdputs(" in "); - cmdlist(n->nfor.args, 1); - cmdputs("; do "); - cmdtxt(n->nfor.body); - cmdputs("; done"); - break; - case NCASE: - cmdputs("case "); - cmdputs(n->ncase.expr->narg.text); - cmdputs(" in "); - for (np = n->ncase.cases; np; np = np->nclist.next) { - cmdtxt(np->nclist.pattern); - cmdputs(") "); - cmdtxt(np->nclist.body); - cmdputs(";; "); - } - cmdputs("esac"); - break; - case NDEFUN: - cmdputs(n->narg.text); - cmdputs("() { ... }"); - break; - case NCMD: - cmdlist(n->ncmd.args, 1); - cmdlist(n->ncmd.redirect, 0); - break; - case NARG: - cmdputs(n->narg.text); - break; - case NTO: - p = ">"; i = 1; goto redir; - case NCLOBBER: - p = ">|"; i = 1; goto redir; - case NAPPEND: - p = ">>"; i = 1; goto redir; - case NTOFD: - p = ">&"; i = 1; goto redir; - case NFROM: - p = "<"; i = 0; goto redir; - case NFROMFD: - p = "<&"; i = 0; goto redir; - case NFROMTO: - p = "<>"; i = 0; goto redir; -redir: - if (n->nfile.fd != i) { - s[0] = n->nfile.fd + '0'; - s[1] = '\0'; - cmdputs(s); - } - cmdputs(p); - if (n->type == NTOFD || n->type == NFROMFD) { - s[0] = n->ndup.dupfd + '0'; - s[1] = '\0'; - cmdputs(s); - } else { - cmdtxt(n->nfile.fname); - } - break; - case NHERE: - case NXHERE: - cmdputs("<<..."); - break; - default: - cmdputs("???"); - break; - } -} - -STATIC void -cmdlist(union node *np, int sep) -{ - for (; np; np = np->narg.next) { - if (!sep) - cmdputs(" "); - cmdtxt(np); - if (sep && np->narg.next) - cmdputs(" "); - } -} - - -STATIC void -cmdputs(const char *s) -{ - const char *p, *str = 0; - char c, cc[2] = " "; - char *nextc; - int nleft; - int subtype = 0; - int quoted = 0; - static char vstype[16][4] = { "", "}", "-", "+", "?", "=", - "#", "##", "%", "%%" }; - - p = s; - nextc = cmdnextc; - nleft = cmdnleft; - while (nleft > 0 && (c = *p++) != 0) { - switch (c) { - case CTLESC: - c = *p++; - break; - case CTLVAR: - subtype = *p++; - if ((subtype & VSTYPE) == VSLENGTH) - str = "${#"; - else - str = "${"; - if (!(subtype & VSQUOTE) != !(quoted & 1)) { - quoted ^= 1; - c = '"'; - } else - c = *str++; - break; - case CTLENDVAR: - if (quoted & 1) { - c = '"'; - str = "}"; - } else - c = '}'; - quoted >>= 1; - subtype = 0; - break; - case CTLBACKQ: - c = '$'; - str = "(...)"; - break; - case CTLBACKQ+CTLQUOTE: - c = '"'; - str = "$(...)\""; - break; - case CTLARI: - c = '$'; - str = "(("; - break; - case CTLENDARI: - c = ')'; - str = ")"; - break; - case CTLQUOTEMARK: - quoted ^= 1; - c = '"'; - break; - case '=': - if (subtype == 0) - break; - str = vstype[subtype & VSTYPE]; - if (subtype & VSNUL) - c = ':'; - else - c = *str++; - if (c != '}') - quoted <<= 1; - break; - case '\'': - case '\\': - case '"': - case '$': - /* These can only happen inside quotes */ - cc[0] = c; - str = cc; - c = '\\'; - break; - default: - break; - } - do { - *nextc++ = c; - } while (--nleft > 0 && str && (c = *str++)); - str = 0; - } - if ((quoted & 1) && nleft) { - *nextc++ = '"'; - nleft--; - } - cmdnleft = nleft; - cmdnextc = nextc; -} diff --git a/sh/jobs.h b/sh/jobs.h deleted file mode 100644 index 47e76c245573e3b2b68e0fb64b37fdb0e0b3fe7a..0000000000000000000000000000000000000000 --- a/sh/jobs.h +++ /dev/null @@ -1,106 +0,0 @@ -/* $NetBSD: jobs.h,v 1.19 2003/11/27 21:16:14 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)jobs.h 8.2 (Berkeley) 5/4/95 - */ - -#include "output.h" - -/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ -#define FORK_FG 0 -#define FORK_BG 1 -#define FORK_NOJOB 2 - -/* mode flags for showjob(s) */ -#define SHOW_PGID 0x01 /* only show pgid - for jobs -p */ -#define SHOW_MULTILINE 0x02 /* one line per process */ -#define SHOW_PID 0x04 /* include process pid */ -#define SHOW_CHANGED 0x08 /* only jobs whose state has changed */ -#define SHOW_SIGNALLED 0x10 /* only if stopped/exited on signal */ -#define SHOW_ISSIG 0x20 /* job was signalled */ -#define SHOW_NO_FREE 0x40 /* do not free job */ - - -/* - * A job structure contains information about a job. A job is either a - * single process or a set of processes contained in a pipeline. In the - * latter case, pidlist will be non-NULL, and will point to a -1 terminated - * array of pids. - */ -#define MAXCMDTEXT 200 - -struct procstat { - pid_t pid; /* process id */ - int status; /* last process status from wait() */ - char cmd[MAXCMDTEXT];/* text of command being run */ -}; - -struct job { - struct procstat ps0; /* status of process */ - struct procstat *ps; /* status or processes when more than one */ - int nprocs; /* number of processes */ - pid_t pgrp; /* process group of this job */ - char state; -#define JOBRUNNING 0 /* at least one proc running */ -#define JOBSTOPPED 1 /* all procs are stopped */ -#define JOBDONE 2 /* all procs are completed */ - char used; /* true if this entry is in used */ - char changed; /* true if status has changed */ -#if JOBS - char jobctl; /* job running under job control */ - int prev_job; /* previous job index */ -#endif -}; - -extern pid_t backgndpid; /* pid of last background process */ -extern int job_warning; /* user was warned about stopped jobs */ - -void setjobctl(int); -int fgcmd(int, char **); -int bgcmd(int, char **); -int jobscmd(int, char **); -void showjobs(struct output *, int); -int waitcmd(int, char **); -int jobidcmd(int, char **); -struct job *makejob(union node *, int); -int forkshell(struct job *, union node *, int); -void forkchild(struct job *, union node *, int, int); -int forkparent(struct job *, union node *, int, pid_t); -int waitforjob(struct job *); -int stoppedjobs(void); -void commandtext(struct procstat *, union node *); -int getjobpgrp(const char *); - -#if ! JOBS -#define setjobctl(on) /* do nothing */ -#endif diff --git a/sh/machdep.h b/sh/machdep.h deleted file mode 100644 index 14e803bf72b103253644311bd8d3d5bcd544235d..0000000000000000000000000000000000000000 --- a/sh/machdep.h +++ /dev/null @@ -1,47 +0,0 @@ -/* $NetBSD: machdep.h,v 1.11 2003/08/07 09:05:33 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)machdep.h 8.2 (Berkeley) 5/4/95 - */ - -/* - * Most machines require the value returned from malloc to be aligned - * in some way. The following macro will get this right on many machines. - */ - -#define SHELL_SIZE (sizeof(union {int i; char *cp; double d; }) - 1) -/* - * It appears that grabstackstr() will barf with such alignments - * because stalloc() will return a string allocated in a new stackblock. - */ -#define SHELL_ALIGN(nbytes) (((nbytes) + SHELL_SIZE) & ~SHELL_SIZE) diff --git a/sh/main.c b/sh/main.c deleted file mode 100644 index 43b154f469c26ff00ccf7bbbaadc540c7e2837b4..0000000000000000000000000000000000000000 --- a/sh/main.c +++ /dev/null @@ -1,394 +0,0 @@ -/* $NetBSD: main.c,v 1.48 2003/09/14 12:09:29 jmmv Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; -#else -__RCSID("$NetBSD: main.c,v 1.48 2003/09/14 12:09:29 jmmv Exp $"); -#endif -#endif /* not lint */ - -#include <errno.h> -#include <stdio.h> -#include <signal.h> -#include <sys/stat.h> -#include <unistd.h> -#include <fcntl.h> - - -#include "shell.h" -#include "main.h" -#include "options.h" -#include "output.h" -#include "parser.h" -#include "nodes.h" -#include "expand.h" -#include "eval.h" -#include "jobs.h" -#include "input.h" -#include "trap.h" -#include "var.h" -#include "show.h" -#include "memalloc.h" -#include "error.h" -#include "init.h" -#include "mystring.h" -#include "exec.h" -#include "cd.h" - -#define PROFILE 0 - -int rootpid; -int rootshell; -STATIC union node *curcmd; -STATIC union node *prevcmd; -#if PROFILE -short profile_buf[16384]; -extern int etext(); -#endif - -STATIC void read_profile(const char *); -STATIC char *find_dot_file(char *); -int main(int, char **); - -/* - * Main routine. We initialize things, parse the arguments, execute - * profiles if we're a login shell, and then call cmdloop to execute - * commands. The setjmp call sets up the location to jump to when an - * exception occurs. When an exception occurs the variable "state" - * is used to figure out how far we had gotten. - */ - -int -main(int argc, char **argv) -{ - struct jmploc jmploc; - struct stackmark smark; - volatile int state; - char *shinit; - -#if PROFILE - monitor(4, etext, profile_buf, sizeof profile_buf, 50); -#endif - state = 0; - if (setjmp(jmploc.loc)) { - /* - * When a shell procedure is executed, we raise the - * exception EXSHELLPROC to clean up before executing - * the shell procedure. - */ - switch (exception) { - case EXSHELLPROC: - rootpid = getpid(); - rootshell = 1; - minusc = NULL; - state = 3; - break; - - case EXEXEC: - exitstatus = exerrno; - break; - - case EXERROR: - exitstatus = 2; - break; - - default: - break; - } - - if (exception != EXSHELLPROC) { - if (state == 0 || iflag == 0 || ! rootshell) - exitshell(exitstatus); - } - reset(); - if (exception == EXINT -#if ATTY - && (! attyset() || equal(termval(), "emacs")) -#endif - ) { - out2c('\n'); - flushout(&errout); - } - popstackmark(&smark); - FORCEINTON; /* enable interrupts */ - if (state == 1) - goto state1; - else if (state == 2) - goto state2; - else if (state == 3) - goto state3; - else - goto state4; - } - handler = &jmploc; -#ifdef DEBUG -#if DEBUG == 2 - debug = 1; -#endif - opentrace(); - trputs("Shell args: "); trargs(argv); -#endif - rootpid = getpid(); - rootshell = 1; - init(); - setstackmark(&smark); - procargs(argc, argv); - if (argv[0] && argv[0][0] == '-') { - state = 1; - read_profile("/etc/profile"); -state1: - state = 2; - read_profile(".profile"); - } -state2: - state = 3; - if (getuid() == geteuid() && getgid() == getegid()) { - if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { - state = 3; - read_profile(shinit); - } - } -state3: - state = 4; - if (sflag == 0 || minusc) { - static int sigs[] = { - SIGINT, SIGQUIT, SIGHUP, -#ifdef SIGTSTP - SIGTSTP, -#endif - SIGPIPE - }; -#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) - int i; - - for (i = 0; i < SIGSSIZE; i++) - setsignal(sigs[i], 0); - } - - if (minusc) - evalstring(minusc, 0); - - if (sflag || minusc == NULL) { -state4: /* XXX ??? - why isn't this before the "if" statement */ - cmdloop(1); - } -#if PROFILE - monitor(0); -#endif - exitshell(exitstatus); - /* NOTREACHED */ -} - - -/* - * Read and execute commands. "Top" is nonzero for the top level command - * loop; it turns on prompting if the shell is interactive. - */ - -void -cmdloop(int top) -{ - union node *n; - struct stackmark smark; - int inter; - int numeof = 0; - - TRACE(("cmdloop(%d) called\n", top)); - setstackmark(&smark); - for (;;) { - if (pendingsigs) - dotrap(); - inter = 0; - if (iflag && top) { - inter = 1; - showjobs(out2, SHOW_CHANGED); - flushout(&errout); - } - n = parsecmd(inter); - /* showtree(n); DEBUG */ - if (n == NEOF) { - if (!top || numeof >= 50) - break; - if (!stoppedjobs()) { - if (!Iflag) - break; - out2str("\nUse \"exit\" to leave shell.\n"); - } - numeof++; - } else if (n != NULL && nflag == 0) { - job_warning = (job_warning == 2) ? 1 : 0; - numeof = 0; - evaltree(n, 0); - } - popstackmark(&smark); - setstackmark(&smark); - if (evalskip == SKIPFILE) { - evalskip = 0; - break; - } - } - popstackmark(&smark); -} - - - -/* - * Read /etc/profile or .profile. Return on error. - */ - -STATIC void -read_profile(const char *name) -{ - int fd; - int xflag_set = 0; - int vflag_set = 0; - - INTOFF; - if ((fd = open(name, O_RDONLY)) >= 0) - setinputfd(fd, 1); - INTON; - if (fd < 0) - return; - /* -q turns off -x and -v just when executing init files */ - if (qflag) { - if (xflag) - xflag = 0, xflag_set = 1; - if (vflag) - vflag = 0, vflag_set = 1; - } - cmdloop(0); - if (qflag) { - if (xflag_set) - xflag = 1; - if (vflag_set) - vflag = 1; - } - popfile(); -} - - - -/* - * Read a file containing shell functions. - */ - -void -readcmdfile(char *name) -{ - int fd; - - INTOFF; - if ((fd = open(name, O_RDONLY)) >= 0) - setinputfd(fd, 1); - else - error("Can't open %s", name); - INTON; - cmdloop(0); - popfile(); -} - - - -/* - * Take commands from a file. To be compatible we should do a path - * search for the file, which is necessary to find sub-commands. - */ - - -STATIC char * -find_dot_file(char *basename) -{ - char *fullname; - const char *path = pathval(); - struct stat statb; - - /* don't try this for absolute or relative paths */ - if (strchr(basename, '/')) - return basename; - - while ((fullname = padvance(&path, basename)) != NULL) { - if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { - /* - * Don't bother freeing here, since it will - * be freed by the caller. - */ - return fullname; - } - stunalloc(fullname); - } - - /* not found in the PATH */ - error("%s: not found", basename); - /* NOTREACHED */ -} - -int -dotcmd(int argc, char **argv) -{ - exitstatus = 0; - - if (argc >= 2) { /* That's what SVR2 does */ - char *fullname; - struct stackmark smark; - - setstackmark(&smark); - fullname = find_dot_file(argv[1]); - setinputfile(fullname, 1); - commandname = fullname; - cmdloop(0); - popfile(); - popstackmark(&smark); - } - return exitstatus; -} - - -int -exitcmd(int argc, char **argv) -{ - if (stoppedjobs()) - return 0; - if (argc > 1) - exitstatus = number(argv[1]); - exitshell(exitstatus); - /* NOTREACHED */ -} diff --git a/sh/main.h b/sh/main.h deleted file mode 100644 index d198e2dddc6be2dea16def4defda8d19d393948b..0000000000000000000000000000000000000000 --- a/sh/main.h +++ /dev/null @@ -1,43 +0,0 @@ -/* $NetBSD: main.h,v 1.10 2003/08/07 09:05:34 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)main.h 8.2 (Berkeley) 5/4/95 - */ - -extern int rootpid; /* pid of main shell */ -extern int rootshell; /* true if we aren't a child of the main shell */ - -void readcmdfile(char *); -void cmdloop(int); -int dotcmd(int, char **); -int exitcmd(int, char **); diff --git a/sh/memalloc.c b/sh/memalloc.c deleted file mode 100644 index 07c14dbe5b0c9262a07b2b77206aae7a97b3a291..0000000000000000000000000000000000000000 --- a/sh/memalloc.c +++ /dev/null @@ -1,307 +0,0 @@ -/* $NetBSD: memalloc.c,v 1.28 2003/08/07 09:05:34 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: memalloc.c,v 1.28 2003/08/07 09:05:34 agc Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> -#include <unistd.h> - -#include "shell.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "machdep.h" -#include "mystring.h" - -/* - * Like malloc, but returns an error when out of space. - */ - -pointer -ckmalloc(int nbytes) -{ - pointer p; - - p = malloc(nbytes); - if (p == NULL) - error("Out of space"); - return p; -} - - -/* - * Same for realloc. - */ - -pointer -ckrealloc(pointer p, int nbytes) -{ - p = realloc(p, nbytes); - if (p == NULL) - error("Out of space"); - return p; -} - - -/* - * Make a copy of a string in safe storage. - */ - -char * -savestr(const char *s) -{ - char *p; - - p = ckmalloc(strlen(s) + 1); - scopy(s, p); - return p; -} - - -/* - * Parse trees for commands are allocated in lifo order, so we use a stack - * to make this more efficient, and also to avoid all sorts of exception - * handling code to handle interrupts in the middle of a parse. - * - * The size 504 was chosen because the Ultrix malloc handles that size - * well. - */ - -#define MINSIZE 504 /* minimum size of a block */ - -struct stack_block { - struct stack_block *prev; - char space[MINSIZE]; -}; - -struct stack_block stackbase; -struct stack_block *stackp = &stackbase; -struct stackmark *markp; -char *stacknxt = stackbase.space; -int stacknleft = MINSIZE; -int sstrnleft; -int herefd = -1; - -pointer -stalloc(int nbytes) -{ - char *p; - - nbytes = SHELL_ALIGN(nbytes); - if (nbytes > stacknleft) { - int blocksize; - struct stack_block *sp; - - blocksize = nbytes; - if (blocksize < MINSIZE) - blocksize = MINSIZE; - INTOFF; - sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize); - sp->prev = stackp; - stacknxt = sp->space; - stacknleft = blocksize; - stackp = sp; - INTON; - } - p = stacknxt; - stacknxt += nbytes; - stacknleft -= nbytes; - return p; -} - - -void -stunalloc(pointer p) -{ - if (p == NULL) { /*DEBUG */ - write(2, "stunalloc\n", 10); - abort(); - } - stacknleft += stacknxt - (char *)p; - stacknxt = p; -} - - - -void -setstackmark(struct stackmark *mark) -{ - mark->stackp = stackp; - mark->stacknxt = stacknxt; - mark->stacknleft = stacknleft; - mark->marknext = markp; - markp = mark; -} - - -void -popstackmark(struct stackmark *mark) -{ - struct stack_block *sp; - - INTOFF; - markp = mark->marknext; - while (stackp != mark->stackp) { - sp = stackp; - stackp = sp->prev; - ckfree(sp); - } - stacknxt = mark->stacknxt; - stacknleft = mark->stacknleft; - INTON; -} - - -/* - * When the parser reads in a string, it wants to stick the string on the - * stack and only adjust the stack pointer when it knows how big the - * string is. Stackblock (defined in stack.h) returns a pointer to a block - * of space on top of the stack and stackblocklen returns the length of - * this block. Growstackblock will grow this space by at least one byte, - * possibly moving it (like realloc). Grabstackblock actually allocates the - * part of the block that has been used. - */ - -void -growstackblock(void) -{ - int newlen = SHELL_ALIGN(stacknleft * 2 + 100); - - if (stacknxt == stackp->space && stackp != &stackbase) { - struct stack_block *oldstackp; - struct stackmark *xmark; - struct stack_block *sp; - - INTOFF; - oldstackp = stackp; - sp = stackp; - stackp = sp->prev; - sp = ckrealloc((pointer)sp, - sizeof(struct stack_block) - MINSIZE + newlen); - sp->prev = stackp; - stackp = sp; - stacknxt = sp->space; - stacknleft = newlen; - - /* - * Stack marks pointing to the start of the old block - * must be relocated to point to the new block - */ - xmark = markp; - while (xmark != NULL && xmark->stackp == oldstackp) { - xmark->stackp = stackp; - xmark->stacknxt = stacknxt; - xmark->stacknleft = stacknleft; - xmark = xmark->marknext; - } - INTON; - } else { - char *oldspace = stacknxt; - int oldlen = stacknleft; - char *p = stalloc(newlen); - - (void)memcpy(p, oldspace, oldlen); - stacknxt = p; /* free the space */ - stacknleft += newlen; /* we just allocated */ - } -} - -void -grabstackblock(int len) -{ - len = SHELL_ALIGN(len); - stacknxt += len; - stacknleft -= len; -} - -/* - * The following routines are somewhat easier to use than the above. - * The user declares a variable of type STACKSTR, which may be declared - * to be a register. The macro STARTSTACKSTR initializes things. Then - * the user uses the macro STPUTC to add characters to the string. In - * effect, STPUTC(c, p) is the same as *p++ = c except that the stack is - * grown as necessary. When the user is done, she can just leave the - * string there and refer to it using stackblock(). Or she can allocate - * the space for it using grabstackstr(). If it is necessary to allow - * someone else to use the stack temporarily and then continue to grow - * the string, the user should use grabstack to allocate the space, and - * then call ungrabstr(p) to return to the previous mode of operation. - * - * USTPUTC is like STPUTC except that it doesn't check for overflow. - * CHECKSTACKSPACE can be called before USTPUTC to ensure that there - * is space for at least one character. - */ - -char * -growstackstr(void) -{ - int len = stackblocksize(); - if (herefd >= 0 && len >= 1024) { - xwrite(herefd, stackblock(), len); - sstrnleft = len - 1; - return stackblock(); - } - growstackblock(); - sstrnleft = stackblocksize() - len - 1; - return stackblock() + len; -} - -/* - * Called from CHECKSTRSPACE. - */ - -char * -makestrspace(void) -{ - int len = stackblocksize() - sstrnleft; - growstackblock(); - sstrnleft = stackblocksize() - len; - return stackblock() + len; -} - -void -ungrabstackstr(char *s, char *p) -{ - stacknleft += stacknxt - s; - stacknxt = s; - sstrnleft = stacknleft - (p - s); - -} diff --git a/sh/memalloc.h b/sh/memalloc.h deleted file mode 100644 index e7938802c0f523bdbfc45af6e2ba273318eb34f7..0000000000000000000000000000000000000000 --- a/sh/memalloc.h +++ /dev/null @@ -1,77 +0,0 @@ -/* $NetBSD: memalloc.h,v 1.14 2003/08/07 09:05:34 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)memalloc.h 8.2 (Berkeley) 5/4/95 - */ - -struct stackmark { - struct stack_block *stackp; - char *stacknxt; - int stacknleft; - struct stackmark *marknext; -}; - - -extern char *stacknxt; -extern int stacknleft; -extern int sstrnleft; -extern int herefd; - -pointer ckmalloc(int); -pointer ckrealloc(pointer, int); -char *savestr(const char *); -pointer stalloc(int); -void stunalloc(pointer); -void setstackmark(struct stackmark *); -void popstackmark(struct stackmark *); -void growstackblock(void); -void grabstackblock(int); -char *growstackstr(void); -char *makestrspace(void); -void ungrabstackstr(char *, char *); - - - -#define stackblock() stacknxt -#define stackblocksize() stacknleft -#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() -#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) -#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); } -#define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) -#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) -#define STUNPUTC(p) (++sstrnleft, --p) -#define STTOPC(p) p[-1] -#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) -#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft) - -#define ckfree(p) free((pointer)(p)) diff --git a/sh/miscbltin.c b/sh/miscbltin.c deleted file mode 100644 index 1a8e252bd99085ede74d6c146ef6c84eef468f2b..0000000000000000000000000000000000000000 --- a/sh/miscbltin.c +++ /dev/null @@ -1,447 +0,0 @@ -/* $NetBSD: miscbltin.c,v 1.34.2.1 2005/04/07 11:34:20 tron Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: miscbltin.c,v 1.34.2.1 2005/04/07 11:34:20 tron Exp $"); -#endif -#endif /* not lint */ - -/* - * Miscelaneous builtins. - */ - -#include <sys/types.h> /* quad_t */ -#include <sys/param.h> /* BSD4_4 */ -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <unistd.h> -#include <stdlib.h> -#include <ctype.h> -#include <errno.h> - -#include "shell.h" -#include "options.h" -#include "var.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "miscbltin.h" -#include "mystring.h" - -#undef rflag - - - -/* - * The read builtin. - * Backslahes escape the next char unless -r is specified. - * - * This uses unbuffered input, which may be avoidable in some cases. - * - * Note that if IFS=' :' then read x y should work so that: - * 'a b' x='a', y='b' - * ' a b ' x='a', y='b' - * ':b' x='', y='b' - * ':' x='', y='' - * '::' x='', y='' - * ': :' x='', y='' - * ':::' x='', y='::' - * ':b c:' x='', y='b c:' - */ - -int -readcmd(int argc, char **argv) -{ - char **ap; - char c; - int rflag; - char *prompt; - const char *ifs; - char *p; - int startword; - int status; - int i; - int is_ifs; - int saveall = 0; - - rflag = 0; - prompt = NULL; - while ((i = nextopt("p:r")) != '\0') { - if (i == 'p') - prompt = optionarg; - else - rflag = 1; - } - - if (prompt && isatty(0)) { - out2str(prompt); - flushall(); - } - - if (*(ap = argptr) == NULL) - error("arg count"); - - if ((ifs = bltinlookup("IFS", 1)) == NULL) - ifs = " \t\n"; - - status = 0; - startword = 2; - STARTSTACKSTR(p); - for (;;) { - if (read(0, &c, 1) != 1) { - status = 1; - break; - } - if (c == '\0') - continue; - if (c == '\\' && !rflag) { - if (read(0, &c, 1) != 1) { - status = 1; - break; - } - if (c != '\n') - STPUTC(c, p); - continue; - } - if (c == '\n') - break; - if (strchr(ifs, c)) - is_ifs = strchr(" \t\n", c) ? 1 : 2; - else - is_ifs = 0; - - if (startword != 0) { - if (is_ifs == 1) { - /* Ignore leading IFS whitespace */ - if (saveall) - STPUTC(c, p); - continue; - } - if (is_ifs == 2 && startword == 1) { - /* Only one non-whitespace IFS per word */ - startword = 2; - if (saveall) - STPUTC(c, p); - continue; - } - } - - if (is_ifs == 0) { - /* append this character to the current variable */ - startword = 0; - if (saveall) - /* Not just a spare terminator */ - saveall++; - STPUTC(c, p); - continue; - } - - /* end of variable... */ - startword = is_ifs; - - if (ap[1] == NULL) { - /* Last variable needs all IFS chars */ - saveall++; - STPUTC(c, p); - continue; - } - - STACKSTRNUL(p); - setvar(*ap, stackblock(), 0); - ap++; - STARTSTACKSTR(p); - } - STACKSTRNUL(p); - - /* Remove trailing IFS chars */ - for (; stackblock() <= --p; *p = 0) { - if (!strchr(ifs, *p)) - break; - if (strchr(" \t\n", *p)) - /* Always remove whitespace */ - continue; - if (saveall > 1) - /* Don't remove non-whitespace unless it was naked */ - break; - } - setvar(*ap, stackblock(), 0); - - /* Set any remaining args to "" */ - while (*++ap != NULL) - setvar(*ap, nullstr, 0); - return status; -} - - - -int -umaskcmd(int argc, char **argv) -{ - char *ap; - int mask; - int i; - int symbolic_mode = 0; - - while ((i = nextopt("S")) != '\0') { - symbolic_mode = 1; - } - - INTOFF; - mask = umask(0); - umask(mask); - INTON; - - if ((ap = *argptr) == NULL) { - if (symbolic_mode) { - char u[4], g[4], o[4]; - - i = 0; - if ((mask & S_IRUSR) == 0) - u[i++] = 'r'; - if ((mask & S_IWUSR) == 0) - u[i++] = 'w'; - if ((mask & S_IXUSR) == 0) - u[i++] = 'x'; - u[i] = '\0'; - - i = 0; - if ((mask & S_IRGRP) == 0) - g[i++] = 'r'; - if ((mask & S_IWGRP) == 0) - g[i++] = 'w'; - if ((mask & S_IXGRP) == 0) - g[i++] = 'x'; - g[i] = '\0'; - - i = 0; - if ((mask & S_IROTH) == 0) - o[i++] = 'r'; - if ((mask & S_IWOTH) == 0) - o[i++] = 'w'; - if ((mask & S_IXOTH) == 0) - o[i++] = 'x'; - o[i] = '\0'; - - out1fmt("u=%s,g=%s,o=%s\n", u, g, o); - } else { - out1fmt("%.4o\n", mask); - } - } else { - if (isdigit((unsigned char)*ap)) { - mask = 0; - do { - if (*ap >= '8' || *ap < '0') - error("Illegal number: %s", argv[1]); - mask = (mask << 3) + (*ap - '0'); - } while (*++ap != '\0'); - umask(mask); - } else - error("Illegal mode: %s", ap); - } - return 0; -} - -typedef unsigned long rlim_t; - -#if 1 -/* - * ulimit builtin - * - * This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and - * Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with - * ash by J.T. Conklin. - * - * Public domain. - */ - -struct limits { - const char *name; - int cmd; - int factor; /* multiply by to get rlim_{cur,max} values */ - char option; -}; - -static const struct limits limits[] = { -#ifdef RLIMIT_CPU - { "time(seconds)", RLIMIT_CPU, 1, 't' }, -#endif -#ifdef RLIMIT_FSIZE - { "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, -#endif -#ifdef RLIMIT_DATA - { "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, -#endif -#ifdef RLIMIT_STACK - { "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, -#endif -#ifdef RLIMIT_CORE - { "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, -#endif -#ifdef RLIMIT_RSS - { "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, -#endif -#ifdef RLIMIT_MEMLOCK - { "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, -#endif -#ifdef RLIMIT_NPROC - { "process(processes)", RLIMIT_NPROC, 1, 'p' }, -#endif -#ifdef RLIMIT_NOFILE - { "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, -#endif -#ifdef RLIMIT_VMEM - { "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, -#endif -#ifdef RLIMIT_SWAP - { "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, -#endif -#ifdef RLIMIT_SBSIZE - { "sbsize(bytes)", RLIMIT_SBSIZE, 1, 'b' }, -#endif - { (char *) 0, 0, 0, '\0' } -}; - -int -ulimitcmd(int argc, char **argv) -{ - int c; - rlim_t val = 0; - enum { SOFT = 0x1, HARD = 0x2 } - how = SOFT | HARD; - const struct limits *l; - int set, all = 0; - int optc, what; - struct rlimit limit; - - what = 'f'; - while ((optc = nextopt("HSabtfdsmcnpl")) != '\0') - switch (optc) { - case 'H': - how = HARD; - break; - case 'S': - how = SOFT; - break; - case 'a': - all = 1; - break; - default: - what = optc; - } - - for (l = limits; l->name && l->option != what; l++) - ; - if (!l->name) - error("internal error (%c)", what); - - set = *argptr ? 1 : 0; - if (set) { - char *p = *argptr; - - if (all || argptr[1]) - error("too many arguments"); - if (strcmp(p, "unlimited") == 0) - val = RLIM_INFINITY; - else { - val = (rlim_t) 0; - - while ((c = *p++) >= '0' && c <= '9') - { - val = (val * 10) + (long)(c - '0'); - if ((long)val < 0) - break; - } - if (c) - error("bad number"); - val *= l->factor; - } - } - if (all) { - for (l = limits; l->name; l++) { - getrlimit(l->cmd, &limit); - if (how & SOFT) - val = limit.rlim_cur; - else if (how & HARD) - val = limit.rlim_max; - - out1fmt("%-20s ", l->name); - if (val == RLIM_INFINITY) - out1fmt("unlimited\n"); - else - { - val /= l->factor; -#ifdef BSD4_4 - out1fmt("%lld\n", (long long) val); -#else - out1fmt("%ld\n", (long) val); -#endif - } - } - return 0; - } - - getrlimit(l->cmd, &limit); - if (set) { - if (how & HARD) - limit.rlim_max = val; - if (how & SOFT) - limit.rlim_cur = val; - if (setrlimit(l->cmd, &limit) < 0) - error("error setting limit (%s)", strerror(errno)); - } else { - if (how & SOFT) - val = limit.rlim_cur; - else if (how & HARD) - val = limit.rlim_max; - - if (val == RLIM_INFINITY) - out1fmt("unlimited\n"); - else - { - val /= l->factor; -#ifdef BSD4_4 - out1fmt("%lld\n", (long long) val); -#else - out1fmt("%ld\n", (long) val); -#endif - } - } - return 0; -} -#endif diff --git a/sh/miscbltin.h b/sh/miscbltin.h deleted file mode 100644 index 4c12c82490b8beebc76c6cbabe41f22782644a91..0000000000000000000000000000000000000000 --- a/sh/miscbltin.h +++ /dev/null @@ -1,31 +0,0 @@ -/* $NetBSD: miscbltin.h,v 1.3 2003/08/21 17:57:53 christos Exp $ */ - -/* - * Copyright (c) 1997 Christos Zoulas. 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. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -int readcmd(int, char **); -int umaskcmd(int, char **); -int ulimitcmd(int, char **); diff --git a/sh/mkbuiltins b/sh/mkbuiltins deleted file mode 100644 index 5b1926933cc39487c19e3cf5fbfbc6d19a2081ea..0000000000000000000000000000000000000000 --- a/sh/mkbuiltins +++ /dev/null @@ -1,136 +0,0 @@ -#!/bin/sh - -# $NetBSD: mkbuiltins,v 1.21 2004/06/06 07:03:11 christos Exp $ -# -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. 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. -# -# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95 - -havehist=1 -if [ "X$1" = "X-h" ]; then - havehist=0 - shift -fi - -shell=$1 -builtins=$2 -objdir=$3 - -havejobs=0 -if grep '^#define JOBS[ ]*1' ${shell} > /dev/null -then - havejobs=1 -fi - -exec <$builtins 3> ${objdir}/builtins.c 4> ${objdir}/builtins.h - -echo '/* - * This file was generated by the mkbuiltins program. - */ - -#include "shell.h" -#include "builtins.h" - -const struct builtincmd builtincmd[] = { -' >&3 - -echo '/* - * This file was generated by the mkbuiltins program. - */ - -#include <sys/cdefs.h> - -struct builtincmd { - const char *name; - int (*builtin)(int, char **); -}; - -extern const struct builtincmd builtincmd[]; -extern const struct builtincmd splbltincmd[]; - -' >&4 - -specials= - -while read line -do - set -- $line - [ -z "$1" ] && continue - case "$1" in - \#if*|\#def*|\#end*) - echo $line >&3 - echo $line >&4 - continue - ;; - esac - l1="${line###}" - [ "$l1" != "$line" ] && continue - - - func=$1 - shift - [ x"$1" = x'-j' ] && { - [ $havejobs = 0 ] && continue - shift - } - [ x"$1" = x'-h' ] && { - [ $havehist = 0 ] && continue - shift - } - echo 'int '"$func"'(int, char **);' >&4 - while - [ $# != 0 -a "$1" != '#' ] - do - [ "$1" = '-s' ] && { - specials="$specials $2 $func" - shift 2 - continue; - } - [ "$1" = '-u' ] && shift - echo ' { "'$1'", '"$func"' },' >&3 - shift - done -done - -echo ' { 0, 0 },' >&3 -echo '};' >&3 -echo >&3 -echo 'const struct builtincmd splbltincmd[] = {' >&3 - -set -- $specials -while - [ $# != 0 ] -do - echo ' { "'$1'", '"$2"' },' >&3 - shift 2 -done - -echo ' { 0, 0 },' >&3 -echo "};" >&3 diff --git a/sh/mkinit.sh b/sh/mkinit.sh deleted file mode 100644 index cae27dd18df6275ca63f695dbf308ad0228f121f..0000000000000000000000000000000000000000 --- a/sh/mkinit.sh +++ /dev/null @@ -1,197 +0,0 @@ -#! /bin/sh -# $NetBSD: mkinit.sh,v 1.2 2004/06/15 23:09:54 dsl Exp $ - -# Copyright (c) 2003 The NetBSD Foundation, Inc. -# All rights reserved. -# -# This code is derived from software contributed to The NetBSD Foundation -# by David Laight. -# -# 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. -# 3. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - -srcs="$*" - -nl=' -' -openparen='(' -backslash='\' - -includes=' "shell.h" "mystring.h" "init.h" ' -defines= -decles= -event_init= -event_reset= -event_shellproc= - -for src in $srcs; do - exec <$src - decnl="$nl" - while IFS=; read -r line; do - [ "$line" = x ] - case "$line " in - INIT["{ "]* ) event=init;; - RESET["{ "]* ) event=reset;; - SHELLPROC["{ "]* ) event=shellproc;; - INCLUDE[\ \ ]* ) - IFS=' ' - set -- $line - # ignore duplicates - [ "${includes}" != "${includes%* $2 }" ] && continue - includes="$includes$2 " - continue - ;; - MKINIT\ ) - # struct declaration - decles="$decles$nl" - while - read -r line - decles="${decles}${line}${nl}" - [ "$line" != "};" ] - do - : - done - decnl="$nl" - continue - ;; - MKINIT["{ "]* ) - # strip initialiser - def=${line#MKINIT} - comment="${def#*;}" - def="${def%;$comment}" - def="${def%%=*}" - def="${def% }" - decles="${decles}${decnl}extern${def};${comment}${nl}" - decnl= - continue - ;; - \#define[\ \ ]* ) - IFS=' ' - set -- $line - # Ignore those with arguments - [ "$2" = "${2##*$openparen}" ] || continue - # and multiline definitions - [ "$line" = "${line%$backslash}" ] || continue - defines="${defines}#undef $2${nl}${line}${nl}" - continue - ;; - * ) continue;; - esac - # code for events - ev="${nl} /* from $src: */${nl} {${nl}" - while - read -r line - [ "$line" != "}" ] - do - # The C program indented by an extra 6 chars using - # tabs then spaces. I need to compare the output :-( - indent=6 - while - l=${line# } - [ "$l" != "$line" ] - do - indent=$(($indent + 8)) - line="$l" - done - while - l=${line# } - [ "$l" != "$line" ] - do - indent=$(($indent + 1)) - line="$l" - done - [ -z "$line" -o "$line" != "${line###}" ] && indent=0 - while - [ $indent -ge 8 ] - do - ev="$ev " - indent="$(($indent - 8))" - done - while - [ $indent -gt 0 ] - do - ev="$ev " - indent="$(($indent - 1))" - done - ev="${ev}${line}${nl}" - done - ev="${ev} }${nl}" - eval event_$event=\"\$event_$event\$ev\" - done -done - -exec >init.c.tmp - -echo "/*" -echo " * This file was generated by the mkinit program." -echo " */" -echo - -IFS=' ' -for f in $includes; do - echo "#include $f" -done - -echo -echo -echo -echo "$defines" -echo -echo "$decles" -echo -echo -echo "/*" -echo " * Initialization code." -echo " */" -echo -echo "void" -echo "init() {" -echo "${event_init%$nl}" -echo "}" -echo -echo -echo -echo "/*" -echo " * This routine is called when an error or an interrupt occurs in an" -echo " * interactive shell and control is returned to the main command loop." -echo " */" -echo -echo "void" -echo "reset() {" -echo "${event_reset%$nl}" -echo "}" -echo -echo -echo -echo "/*" -echo " * This routine is called to initialize the shell to run a shell procedure." -echo " */" -echo -echo "void" -echo "initshellproc() {" -echo "${event_shellproc%$nl}" -echo "}" - -exec >&- -mv init.c.tmp init.c diff --git a/sh/mknodes.sh b/sh/mknodes.sh deleted file mode 100644 index 54d2e3d3d7f3d1dd28bbdd9f23741c7867c8f14f..0000000000000000000000000000000000000000 --- a/sh/mknodes.sh +++ /dev/null @@ -1,217 +0,0 @@ -#! /bin/sh -# $NetBSD: mknodes.sh,v 1.1 2004/01/16 23:24:38 dsl Exp $ - -# Copyright (c) 2003 The NetBSD Foundation, Inc. -# All rights reserved. -# -# This code is derived from software contributed to The NetBSD Foundation -# by David Laight. -# -# 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. -# 3. Neither the name of The NetBSD Foundation 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. - -nodetypes=$1 -nodes_pat=$2 -objdir="$3" - -exec <$nodetypes -exec >$objdir/nodes.h.tmp - -echo "/*" -echo " * This file was generated by mknodes.sh" -echo " */" -echo - -tagno=0 -while IFS=; read -r line; do - line="${line%%#*}" - IFS=' ' - set -- $line - IFS= - [ -z "$2" ] && continue - case "$line" in - [" "]* ) - IFS=' ' - [ $field = 0 ] && struct_list="$struct_list $struct" - eval field_${struct}_$field=\"\$*\" - eval numfld_$struct=\$field - field=$(($field + 1)) - ;; - * ) - define=$1 - struct=$2 - echo "#define $define $tagno" - tagno=$(($tagno + 1)) - eval define_$struct=\"\$define_$struct \$define\" - struct_define="$struct_define $struct" - field=0 - ;; - esac -done - -echo - -IFS=' ' -for struct in $struct_list; do - echo - echo - echo "struct $struct {" - field=0 - while - eval line=\"\$field_${struct}_$field\" - field=$(($field + 1)) - [ -n "$line" ] - do - IFS=' ' - set -- $line - name=$1 - case $2 in - nodeptr ) type="union node *";; - nodelist ) type="struct nodelist *";; - string ) type="char *";; - int ) type="int ";; - * ) name=; shift 2; type="$*";; - esac - echo " $type$name;" - done - echo "};" -done - -echo -echo -echo "union node {" -echo " int type;" -for struct in $struct_list; do - echo " struct $struct $struct;" -done -echo "};" -echo -echo -echo "struct nodelist {" -echo " struct nodelist *next;" -echo " union node *n;" -echo "};" -echo -echo -echo "union node *copyfunc(union node *);" -echo "void freefunc(union node *);" - -mv $objdir/nodes.h.tmp $objdir/nodes.h || exit 1 - -exec <$nodes_pat -exec >$objdir/nodes.c.tmp - -echo "/*" -echo " * This file was generated by mknodes.sh" -echo " */" -echo - -while IFS=; read -r line; do - IFS=' ' - set -- $line - IFS= - case "$1" in - '%SIZES' ) - echo "static const short nodesize[$tagno] = {" - IFS=' ' - for struct in $struct_define; do - echo " SHELL_ALIGN(sizeof (struct $struct))," - done - echo "};" - ;; - '%CALCSIZE' ) - echo " if (n == NULL)" - echo " return;" - echo " funcblocksize += nodesize[n->type];" - echo " switch (n->type) {" - IFS=' ' - for struct in $struct_list; do - eval defines=\"\$define_$struct\" - for define in $defines; do - echo " case $define:" - done - eval field=\$numfld_$struct - while - [ $field != 0 ] - do - eval line=\"\$field_${struct}_$field\" - field=$(($field - 1)) - IFS=' ' - set -- $line - name=$1 - cl=")" - case $2 in - nodeptr ) fn=calcsize;; - nodelist ) fn=sizenodelist;; - string ) fn="funcstringsize += strlen" - cl=") + 1";; - * ) continue;; - esac - echo " ${fn}(n->$struct.$name${cl};" - done - echo " break;" - done - echo " };" - ;; - '%COPY' ) - echo " if (n == NULL)" - echo " return NULL;" - echo " new = funcblock;" - echo " funcblock = (char *) funcblock + nodesize[n->type];" - echo " switch (n->type) {" - IFS=' ' - for struct in $struct_list; do - eval defines=\"\$define_$struct\" - for define in $defines; do - echo " case $define:" - done - eval field=\$numfld_$struct - while - [ $field != 0 ] - do - eval line=\"\$field_${struct}_$field\" - field=$(($field - 1)) - IFS=' ' - set -- $line - name=$1 - case $2 in - nodeptr ) fn="copynode(";; - nodelist ) fn="copynodelist(";; - string ) fn="nodesavestr(";; - int ) fn=;; - * ) continue;; - esac - f="$struct.$name" - echo " new->$f = ${fn}n->$f${fn:+)};" - done - echo " break;" - done - echo " };" - echo " new->type = n->type;" - ;; - * ) echo "$line";; - esac -done - -mv $objdir/nodes.c.tmp $objdir/nodes.c || exit 1 diff --git a/sh/mktokens b/sh/mktokens deleted file mode 100644 index 25f2e6e3ed53432013289af0b9f53463476c0580..0000000000000000000000000000000000000000 --- a/sh/mktokens +++ /dev/null @@ -1,92 +0,0 @@ -#!/bin/sh - -# $NetBSD: mktokens,v 1.10 2003/08/22 11:22:23 agc Exp $ -# -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. 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. -# -# @(#)mktokens 8.1 (Berkeley) 5/31/93 - -# The following is a list of tokens. The second column is nonzero if the -# token marks the end of a list. The third column is the name to print in -# error messages. - -cat > /tmp/ka$$ <<\! -TEOF 1 end of file -TNL 0 newline -TSEMI 0 ";" -TBACKGND 0 "&" -TAND 0 "&&" -TOR 0 "||" -TPIPE 0 "|" -TLP 0 "(" -TRP 1 ")" -TENDCASE 1 ";;" -TENDBQUOTE 1 "`" -TREDIR 0 redirection -TWORD 0 word -TIF 0 "if" -TTHEN 1 "then" -TELSE 1 "else" -TELIF 1 "elif" -TFI 1 "fi" -TWHILE 0 "while" -TUNTIL 0 "until" -TFOR 0 "for" -TDO 1 "do" -TDONE 1 "done" -TBEGIN 0 "{" -TEND 1 "}" -TCASE 0 "case" -TESAC 1 "esac" -TNOT 0 "!" -! -nl=`wc -l /tmp/ka$$` -exec > token.h -awk '{print "#define " $1 " " NR-1}' /tmp/ka$$ -echo ' -/* Array indicating which tokens mark the end of a list */ -const char tokendlist[] = {' -awk '{print "\t" $2 ","}' /tmp/ka$$ -echo '}; - -const char *const tokname[] = {' -sed -e 's/"/\\"/g' \ - -e 's/[^ ]*[ ][ ]*[^ ]*[ ][ ]*\(.*\)/ "\1",/' \ - /tmp/ka$$ -echo '}; -' -sed 's/"//g' /tmp/ka$$ | awk ' -/TIF/{print "#define KWDOFFSET " NR-1; print ""; - print "const char *const parsekwd[] = {"} -/TIF/,/neverfound/{print " \"" $3 "\","}' -echo ' 0 -};' - -rm /tmp/ka$$ diff --git a/sh/myhistedit.h b/sh/myhistedit.h deleted file mode 100644 index 603a27bc575276b85b3ba238752b25e7438bdebb..0000000000000000000000000000000000000000 --- a/sh/myhistedit.h +++ /dev/null @@ -1,49 +0,0 @@ -/* $NetBSD: myhistedit.h,v 1.10 2003/08/07 09:05:35 agc Exp $ */ - -/*- - * Copyright (c) 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. - * 3. 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. - * - * @(#)myhistedit.h 8.2 (Berkeley) 5/4/95 - */ - -#ifdef WITH_HISTORY -#include <histedit.h> - -extern History *hist; -extern EditLine *el; -extern int displayhist; - -void histedit(void); -void sethistsize(const char *); -void setterm(const char *); -int histcmd(int, char **); -int inputrc(int, char **); -int not_fcnumber(char *); -int str_to_event(const char *, int); -#endif - diff --git a/sh/mystring.c b/sh/mystring.c deleted file mode 100644 index aecf83eb5c66d85ea0930eeff1972e866fc55e44..0000000000000000000000000000000000000000 --- a/sh/mystring.c +++ /dev/null @@ -1,133 +0,0 @@ -/* $NetBSD: mystring.c,v 1.16 2003/08/07 09:05:35 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: mystring.c,v 1.16 2003/08/07 09:05:35 agc Exp $"); -#endif -#endif /* not lint */ - -/* - * String functions. - * - * equal(s1, s2) Return true if strings are equal. - * scopy(from, to) Copy a string. - * scopyn(from, to, n) Like scopy, but checks for overflow. - * number(s) Convert a string of digits to an integer. - * is_number(s) Return true if s is a string of digits. - */ - -#include <stdlib.h> -#include "shell.h" -#include "syntax.h" -#include "error.h" -#include "mystring.h" - - -char nullstr[1]; /* zero length string */ - -/* - * equal - #defined in mystring.h - */ - -/* - * scopy - #defined in mystring.h - */ - - -/* - * scopyn - copy a string from "from" to "to", truncating the string - * if necessary. "To" is always nul terminated, even if - * truncation is performed. "Size" is the size of "to". - */ - -void -scopyn(const char *from, char *to, int size) -{ - - while (--size > 0) { - if ((*to++ = *from++) == '\0') - return; - } - *to = '\0'; -} - - -/* - * prefix -- see if pfx is a prefix of string. - */ - -int -prefix(const char *pfx, const char *string) -{ - while (*pfx) { - if (*pfx++ != *string++) - return 0; - } - return 1; -} - - -/* - * Convert a string of digits to an integer, printing an error message on - * failure. - */ - -int -number(const char *s) -{ - - if (! is_number(s)) - error("Illegal number: %s", s); - return atoi(s); -} - - - -/* - * Check for a valid number. This should be elsewhere. - */ - -int -is_number(const char *p) -{ - do { - if (! is_digit(*p)) - return 0; - } while (*++p != '\0'); - return 1; -} diff --git a/sh/mystring.h b/sh/mystring.h deleted file mode 100644 index 08a73e9e5b25d5bb26c5df33bf2122d8967d0e30..0000000000000000000000000000000000000000 --- a/sh/mystring.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: mystring.h,v 1.11 2003/08/07 09:05:35 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)mystring.h 8.2 (Berkeley) 5/4/95 - */ - -#include <string.h> - -void scopyn(const char *, char *, int); -int prefix(const char *, const char *); -int number(const char *); -int is_number(const char *); - -#define equal(s1, s2) (strcmp(s1, s2) == 0) -#define scopy(s1, s2) ((void)strcpy(s2, s1)) diff --git a/sh/nodes.c b/sh/nodes.c deleted file mode 100644 index 8a2c718b9f585adf505636a03da516d87034831d..0000000000000000000000000000000000000000 --- a/sh/nodes.c +++ /dev/null @@ -1,347 +0,0 @@ -/* - * This file was generated by mknodes.sh - */ - -/* $NetBSD: nodes.c.pat,v 1.12 2004/06/15 22:57:27 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 - */ - -#include <stdlib.h> -/* - * Routine for dealing with parsed shell commands. - */ - -#include "shell.h" -#include "nodes.h" -#include "memalloc.h" -#include "machdep.h" -#include "mystring.h" - - -int funcblocksize; /* size of structures in function */ -int funcstringsize; /* size of strings in node */ -pointer funcblock; /* block to allocate function from */ -char *funcstring; /* block to allocate strings from */ - -static const short nodesize[26] = { - SHELL_ALIGN(sizeof (struct nbinary)), - SHELL_ALIGN(sizeof (struct ncmd)), - SHELL_ALIGN(sizeof (struct npipe)), - SHELL_ALIGN(sizeof (struct nredir)), - SHELL_ALIGN(sizeof (struct nredir)), - SHELL_ALIGN(sizeof (struct nredir)), - SHELL_ALIGN(sizeof (struct nbinary)), - SHELL_ALIGN(sizeof (struct nbinary)), - SHELL_ALIGN(sizeof (struct nif)), - SHELL_ALIGN(sizeof (struct nbinary)), - SHELL_ALIGN(sizeof (struct nbinary)), - SHELL_ALIGN(sizeof (struct nfor)), - SHELL_ALIGN(sizeof (struct ncase)), - SHELL_ALIGN(sizeof (struct nclist)), - SHELL_ALIGN(sizeof (struct narg)), - SHELL_ALIGN(sizeof (struct narg)), - SHELL_ALIGN(sizeof (struct nfile)), - SHELL_ALIGN(sizeof (struct nfile)), - SHELL_ALIGN(sizeof (struct nfile)), - SHELL_ALIGN(sizeof (struct nfile)), - SHELL_ALIGN(sizeof (struct nfile)), - SHELL_ALIGN(sizeof (struct ndup)), - SHELL_ALIGN(sizeof (struct ndup)), - SHELL_ALIGN(sizeof (struct nhere)), - SHELL_ALIGN(sizeof (struct nhere)), - SHELL_ALIGN(sizeof (struct nnot)), -}; - - -STATIC void calcsize(union node *); -STATIC void sizenodelist(struct nodelist *); -STATIC union node *copynode(union node *); -STATIC struct nodelist *copynodelist(struct nodelist *); -STATIC char *nodesavestr(char *); - - - -/* - * Make a copy of a parse tree. - */ - -union node * -copyfunc(n) - union node *n; -{ - if (n == NULL) - return NULL; - funcblocksize = 0; - funcstringsize = 0; - calcsize(n); - funcblock = ckmalloc(funcblocksize + funcstringsize); - funcstring = (char *) funcblock + funcblocksize; - return copynode(n); -} - - - -STATIC void -calcsize(n) - union node *n; -{ - if (n == NULL) - return; - funcblocksize += nodesize[n->type]; - switch (n->type) { - case NSEMI: - case NAND: - case NOR: - case NWHILE: - case NUNTIL: - calcsize(n->nbinary.ch2); - calcsize(n->nbinary.ch1); - break; - case NCMD: - calcsize(n->ncmd.redirect); - calcsize(n->ncmd.args); - break; - case NPIPE: - sizenodelist(n->npipe.cmdlist); - break; - case NREDIR: - case NBACKGND: - case NSUBSHELL: - calcsize(n->nredir.redirect); - calcsize(n->nredir.n); - break; - case NIF: - calcsize(n->nif.elsepart); - calcsize(n->nif.ifpart); - calcsize(n->nif.test); - break; - case NFOR: - funcstringsize += strlen(n->nfor.var) + 1; - calcsize(n->nfor.body); - calcsize(n->nfor.args); - break; - case NCASE: - calcsize(n->ncase.cases); - calcsize(n->ncase.expr); - break; - case NCLIST: - calcsize(n->nclist.body); - calcsize(n->nclist.pattern); - calcsize(n->nclist.next); - break; - case NDEFUN: - case NARG: - sizenodelist(n->narg.backquote); - funcstringsize += strlen(n->narg.text) + 1; - calcsize(n->narg.next); - break; - case NTO: - case NCLOBBER: - case NFROM: - case NFROMTO: - case NAPPEND: - calcsize(n->nfile.fname); - calcsize(n->nfile.next); - break; - case NTOFD: - case NFROMFD: - calcsize(n->ndup.vname); - calcsize(n->ndup.next); - break; - case NHERE: - case NXHERE: - calcsize(n->nhere.doc); - calcsize(n->nhere.next); - break; - case NNOT: - calcsize(n->nnot.com); - break; - }; -} - - - -STATIC void -sizenodelist(lp) - struct nodelist *lp; -{ - while (lp) { - funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); - calcsize(lp->n); - lp = lp->next; - } -} - - - -STATIC union node * -copynode(n) - union node *n; -{ - union node *new; - - if (n == NULL) - return NULL; - new = funcblock; - funcblock = (char *) funcblock + nodesize[n->type]; - switch (n->type) { - case NSEMI: - case NAND: - case NOR: - case NWHILE: - case NUNTIL: - new->nbinary.ch2 = copynode(n->nbinary.ch2); - new->nbinary.ch1 = copynode(n->nbinary.ch1); - break; - case NCMD: - new->ncmd.redirect = copynode(n->ncmd.redirect); - new->ncmd.args = copynode(n->ncmd.args); - new->ncmd.backgnd = n->ncmd.backgnd; - break; - case NPIPE: - new->npipe.cmdlist = copynodelist(n->npipe.cmdlist); - new->npipe.backgnd = n->npipe.backgnd; - break; - case NREDIR: - case NBACKGND: - case NSUBSHELL: - new->nredir.redirect = copynode(n->nredir.redirect); - new->nredir.n = copynode(n->nredir.n); - break; - case NIF: - new->nif.elsepart = copynode(n->nif.elsepart); - new->nif.ifpart = copynode(n->nif.ifpart); - new->nif.test = copynode(n->nif.test); - break; - case NFOR: - new->nfor.var = nodesavestr(n->nfor.var); - new->nfor.body = copynode(n->nfor.body); - new->nfor.args = copynode(n->nfor.args); - break; - case NCASE: - new->ncase.cases = copynode(n->ncase.cases); - new->ncase.expr = copynode(n->ncase.expr); - break; - case NCLIST: - new->nclist.body = copynode(n->nclist.body); - new->nclist.pattern = copynode(n->nclist.pattern); - new->nclist.next = copynode(n->nclist.next); - break; - case NDEFUN: - case NARG: - new->narg.backquote = copynodelist(n->narg.backquote); - new->narg.text = nodesavestr(n->narg.text); - new->narg.next = copynode(n->narg.next); - break; - case NTO: - case NCLOBBER: - case NFROM: - case NFROMTO: - case NAPPEND: - new->nfile.fname = copynode(n->nfile.fname); - new->nfile.fd = n->nfile.fd; - new->nfile.next = copynode(n->nfile.next); - break; - case NTOFD: - case NFROMFD: - new->ndup.vname = copynode(n->ndup.vname); - new->ndup.dupfd = n->ndup.dupfd; - new->ndup.fd = n->ndup.fd; - new->ndup.next = copynode(n->ndup.next); - break; - case NHERE: - case NXHERE: - new->nhere.doc = copynode(n->nhere.doc); - new->nhere.fd = n->nhere.fd; - new->nhere.next = copynode(n->nhere.next); - break; - case NNOT: - new->nnot.com = copynode(n->nnot.com); - break; - }; - new->type = n->type; - return new; -} - - -STATIC struct nodelist * -copynodelist(lp) - struct nodelist *lp; -{ - struct nodelist *start; - struct nodelist **lpp; - - lpp = &start; - while (lp) { - *lpp = funcblock; - funcblock = (char *) funcblock + - SHELL_ALIGN(sizeof(struct nodelist)); - (*lpp)->n = copynode(lp->n); - lp = lp->next; - lpp = &(*lpp)->next; - } - *lpp = NULL; - return start; -} - - - -STATIC char * -nodesavestr(s) - char *s; -{ - register char *p = s; - register char *q = funcstring; - char *rtn = funcstring; - - while ((*q++ = *p++) != 0) - continue; - funcstring = q; - return rtn; -} - - - -/* - * Free a parse tree. - */ - -void -freefunc(n) - union node *n; -{ - if (n) - ckfree(n); -} diff --git a/sh/nodes.c.pat b/sh/nodes.c.pat deleted file mode 100644 index e619a01b053eed6a5ca63d8a641dfaf82dccdfbe..0000000000000000000000000000000000000000 --- a/sh/nodes.c.pat +++ /dev/null @@ -1,166 +0,0 @@ -/* $NetBSD: nodes.c.pat,v 1.12 2004/06/15 22:57:27 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 - */ - -#include <stdlib.h> -/* - * Routine for dealing with parsed shell commands. - */ - -#include "shell.h" -#include "nodes.h" -#include "memalloc.h" -#include "machdep.h" -#include "mystring.h" - - -int funcblocksize; /* size of structures in function */ -int funcstringsize; /* size of strings in node */ -pointer funcblock; /* block to allocate function from */ -char *funcstring; /* block to allocate strings from */ - -%SIZES - - -STATIC void calcsize(union node *); -STATIC void sizenodelist(struct nodelist *); -STATIC union node *copynode(union node *); -STATIC struct nodelist *copynodelist(struct nodelist *); -STATIC char *nodesavestr(char *); - - - -/* - * Make a copy of a parse tree. - */ - -union node * -copyfunc(n) - union node *n; -{ - if (n == NULL) - return NULL; - funcblocksize = 0; - funcstringsize = 0; - calcsize(n); - funcblock = ckmalloc(funcblocksize + funcstringsize); - funcstring = (char *) funcblock + funcblocksize; - return copynode(n); -} - - - -STATIC void -calcsize(n) - union node *n; -{ - %CALCSIZE -} - - - -STATIC void -sizenodelist(lp) - struct nodelist *lp; -{ - while (lp) { - funcblocksize += SHELL_ALIGN(sizeof(struct nodelist)); - calcsize(lp->n); - lp = lp->next; - } -} - - - -STATIC union node * -copynode(n) - union node *n; -{ - union node *new; - - %COPY - return new; -} - - -STATIC struct nodelist * -copynodelist(lp) - struct nodelist *lp; -{ - struct nodelist *start; - struct nodelist **lpp; - - lpp = &start; - while (lp) { - *lpp = funcblock; - funcblock = (char *) funcblock + - SHELL_ALIGN(sizeof(struct nodelist)); - (*lpp)->n = copynode(lp->n); - lp = lp->next; - lpp = &(*lpp)->next; - } - *lpp = NULL; - return start; -} - - - -STATIC char * -nodesavestr(s) - char *s; -{ - register char *p = s; - register char *q = funcstring; - char *rtn = funcstring; - - while ((*q++ = *p++) != 0) - continue; - funcstring = q; - return rtn; -} - - - -/* - * Free a parse tree. - */ - -void -freefunc(n) - union node *n; -{ - if (n) - ckfree(n); -} diff --git a/sh/nodes.h b/sh/nodes.h deleted file mode 100644 index aa750edb43132786fccca6b24293a7719026b24b..0000000000000000000000000000000000000000 --- a/sh/nodes.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * This file was generated by mknodes.sh - */ - -#define NSEMI 0 -#define NCMD 1 -#define NPIPE 2 -#define NREDIR 3 -#define NBACKGND 4 -#define NSUBSHELL 5 -#define NAND 6 -#define NOR 7 -#define NIF 8 -#define NWHILE 9 -#define NUNTIL 10 -#define NFOR 11 -#define NCASE 12 -#define NCLIST 13 -#define NDEFUN 14 -#define NARG 15 -#define NTO 16 -#define NCLOBBER 17 -#define NFROM 18 -#define NFROMTO 19 -#define NAPPEND 20 -#define NTOFD 21 -#define NFROMFD 22 -#define NHERE 23 -#define NXHERE 24 -#define NNOT 25 - - - -struct nbinary { - int type; - union node *ch1; - union node *ch2; -}; - - -struct ncmd { - int type; - int backgnd; - union node *args; - union node *redirect; -}; - - -struct npipe { - int type; - int backgnd; - struct nodelist *cmdlist; -}; - - -struct nredir { - int type; - union node *n; - union node *redirect; -}; - - -struct nif { - int type; - union node *test; - union node *ifpart; - union node *elsepart; -}; - - -struct nfor { - int type; - union node *args; - union node *body; - char *var; -}; - - -struct ncase { - int type; - union node *expr; - union node *cases; -}; - - -struct nclist { - int type; - union node *next; - union node *pattern; - union node *body; -}; - - -struct narg { - int type; - union node *next; - char *text; - struct nodelist *backquote; -}; - - -struct nfile { - int type; - union node *next; - int fd; - union node *fname; - char *expfname; -}; - - -struct ndup { - int type; - union node *next; - int fd; - int dupfd; - union node *vname; -}; - - -struct nhere { - int type; - union node *next; - int fd; - union node *doc; -}; - - -struct nnot { - int type; - union node *com; -}; - - -union node { - int type; - struct nbinary nbinary; - struct ncmd ncmd; - struct npipe npipe; - struct nredir nredir; - struct nif nif; - struct nfor nfor; - struct ncase ncase; - struct nclist nclist; - struct narg narg; - struct nfile nfile; - struct ndup ndup; - struct nhere nhere; - struct nnot nnot; -}; - - -struct nodelist { - struct nodelist *next; - union node *n; -}; - - -union node *copyfunc(union node *); -void freefunc(union node *); diff --git a/sh/nodetypes b/sh/nodetypes deleted file mode 100644 index 4adebc05693bb2ee9617e9a112f15e6c2dbb71fa..0000000000000000000000000000000000000000 --- a/sh/nodetypes +++ /dev/null @@ -1,143 +0,0 @@ -# $NetBSD: nodetypes,v 1.12 2003/08/22 11:22:23 agc Exp $ -# Copyright (c) 1991, 1993 -# The Regents of the University of California. All rights reserved. -# -# This code is derived from software contributed to Berkeley by -# Kenneth Almquist. -# -# 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. -# 3. 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. -# -# @(#)nodetypes 8.2 (Berkeley) 5/4/95 - -# This file describes the nodes used in parse trees. Unindented lines -# contain a node type followed by a structure tag. Subsequent indented -# lines specify the fields of the structure. Several node types can share -# the same structure, in which case the fields of the structure should be -# specified only once. -# -# A field of a structure is described by the name of the field followed -# by a type. The currently implemented types are: -# nodeptr - a pointer to a node -# nodelist - a pointer to a list of nodes -# string - a pointer to a nul terminated string -# int - an integer -# other - any type that can be copied by assignment -# temp - a field that doesn't have to be copied when the node is copied -# The last two types should be followed by the text of a C declaration for -# the field. - -NSEMI nbinary # two commands separated by a semicolon - type int - ch1 nodeptr # the first child - ch2 nodeptr # the second child - -NCMD ncmd # a simple command - type int - backgnd int # set to run command in background - args nodeptr # the arguments - redirect nodeptr # list of file redirections - -NPIPE npipe # a pipeline - type int - backgnd int # set to run pipeline in background - cmdlist nodelist # the commands in the pipeline - -NREDIR nredir # redirection (of a complex command) - type int - n nodeptr # the command - redirect nodeptr # list of file redirections - -NBACKGND nredir # run command in background -NSUBSHELL nredir # run command in a subshell - -NAND nbinary # the && operator -NOR nbinary # the || operator - -NIF nif # the if statement. Elif clauses are handled - type int # using multiple if nodes. - test nodeptr # if test - ifpart nodeptr # then ifpart - elsepart nodeptr # else elsepart - -NWHILE nbinary # the while statement. First child is the test -NUNTIL nbinary # the until statement - -NFOR nfor # the for statement - type int - args nodeptr # for var in args - body nodeptr # do body; done - var string # the for variable - -NCASE ncase # a case statement - type int - expr nodeptr # the word to switch on - cases nodeptr # the list of cases (NCLIST nodes) - -NCLIST nclist # a case - type int - next nodeptr # the next case in list - pattern nodeptr # list of patterns for this case - body nodeptr # code to execute for this case - - -NDEFUN narg # define a function. The "next" field contains - # the body of the function. - -NARG narg # represents a word - type int - next nodeptr # next word in list - text string # the text of the word - backquote nodelist # list of commands in back quotes - -NTO nfile # fd> fname -NCLOBBER nfile # fd>| fname -NFROM nfile # fd< fname -NFROMTO nfile # fd<> fname -NAPPEND nfile # fd>> fname - type int - next nodeptr # next redirection in list - fd int # file descriptor being redirected - fname nodeptr # file name, in a NARG node - expfname temp char *expfname # actual file name - -NTOFD ndup # fd<&dupfd -NFROMFD ndup # fd>&dupfd - type int - next nodeptr # next redirection in list - fd int # file descriptor being redirected - dupfd int # file descriptor to duplicate - vname nodeptr # file name if fd>&$var - - -NHERE nhere # fd<<\! -NXHERE nhere # fd<<! - type int - next nodeptr # next redirection in list - fd int # file descriptor being redirected - doc nodeptr # input to command (NARG node) - -NNOT nnot # ! command (actually pipeline) - type int - com nodeptr diff --git a/sh/options.c b/sh/options.c deleted file mode 100644 index bc833c79040ba124d093887a9068a2d5e3f21c4b..0000000000000000000000000000000000000000 --- a/sh/options.c +++ /dev/null @@ -1,530 +0,0 @@ -/* $NetBSD: options.c,v 1.37 2004/10/30 19:29:27 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: options.c,v 1.37 2004/10/30 19:29:27 christos Exp $"); -#endif -#endif /* not lint */ - -#include <signal.h> -#include <unistd.h> -#include <stdlib.h> - -#include "shell.h" -#define DEFINE_OPTIONS -#include "options.h" -#undef DEFINE_OPTIONS -#include "nodes.h" /* for other header files */ -#include "eval.h" -#include "jobs.h" -#include "input.h" -#include "output.h" -#include "trap.h" -#include "var.h" -#include "memalloc.h" -#include "error.h" -#include "mystring.h" -#ifndef SMALL -#include "myhistedit.h" -#endif -#include "show.h" - -char *arg0; /* value of $0 */ -struct shparam shellparam; /* current positional parameters */ -char **argptr; /* argument list for builtin commands */ -char *optionarg; /* set by nextopt (like getopt) */ -char *optptr; /* used by nextopt */ - -char *minusc; /* argument to -c option */ - - -STATIC void options(int); -STATIC void minus_o(char *, int); -STATIC void setoption(int, int); -STATIC int getopts(char *, char *, char **, char ***, char **); - - -/* - * Process the shell command line arguments. - */ - -void -procargs(int argc, char **argv) -{ - int i; - - argptr = argv; - if (argc > 0) - argptr++; - for (i = 0; i < NOPTS; i++) - optlist[i].val = 2; - options(1); - if (*argptr == NULL && minusc == NULL) - sflag = 1; - if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) - iflag = 1; - if (mflag == 2) - mflag = iflag; - for (i = 0; i < NOPTS; i++) - if (optlist[i].val == 2) - optlist[i].val = 0; -#if DEBUG == 2 - debug = 1; -#endif - arg0 = argv[0]; - if (sflag == 0 && minusc == NULL) { - commandname = argv[0]; - arg0 = *argptr++; - setinputfile(arg0, 0); - commandname = arg0; - } - /* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ - if (minusc != NULL) { - if (argptr == NULL || *argptr == NULL) - error("Bad -c option"); - minusc = *argptr++; - if (*argptr != 0) - arg0 = *argptr++; - } - - shellparam.p = argptr; - shellparam.reset = 1; - /* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ - while (*argptr) { - shellparam.nparam++; - argptr++; - } - optschanged(); -} - - -void -optschanged(void) -{ - setinteractive(iflag); -#ifdef WITH_HISTORY - histedit(); -#endif - setjobctl(mflag); -} - -/* - * Process shell options. The global variable argptr contains a pointer - * to the argument list; we advance it past the options. - */ - -STATIC void -options(int cmdline) -{ - static char empty[] = ""; - char *p; - int val; - int c; - - if (cmdline) - minusc = NULL; - while ((p = *argptr) != NULL) { - argptr++; - if ((c = *p++) == '-') { - val = 1; - if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { - if (!cmdline) { - /* "-" means turn off -x and -v */ - if (p[0] == '\0') - xflag = vflag = 0; - /* "--" means reset params */ - else if (*argptr == NULL) - setparam(argptr); - } - break; /* "-" or "--" terminates options */ - } - } else if (c == '+') { - val = 0; - } else { - argptr--; - break; - } - while ((c = *p++) != '\0') { - if (c == 'c' && cmdline) { - /* command is after shell args*/ - minusc = empty; - } else if (c == 'o') { - minus_o(*argptr, val); - if (*argptr) - argptr++; - } else { - setoption(c, val); - } - } - } -} - -static void -set_opt_val(int i, int val) -{ - int j; - int flag; - - if (val && (flag = optlist[i].opt_set)) { - /* some options (eg vi/emacs) are mutually exclusive */ - for (j = 0; j < NOPTS; j++) - if (optlist[j].opt_set == flag) - optlist[j].val = 0; - } - optlist[i].val = val; -#ifdef DEBUG - if (&optlist[i].val == &debug) - opentrace(); -#endif -} - -STATIC void -minus_o(char *name, int val) -{ - int i; - - if (name == NULL) { - out1str("Current option settings\n"); - for (i = 0; i < NOPTS; i++) - out1fmt("%-16s%s\n", optlist[i].name, - optlist[i].val ? "on" : "off"); - } else { - for (i = 0; i < NOPTS; i++) - if (equal(name, optlist[i].name)) { - set_opt_val(i, val); - return; - } - error("Illegal option -o %s", name); - } -} - - -STATIC void -setoption(int flag, int val) -{ - int i; - - for (i = 0; i < NOPTS; i++) - if (optlist[i].letter == flag) { - set_opt_val( i, val ); - return; - } - error("Illegal option -%c", flag); - /* NOTREACHED */ -} - - - -#ifdef mkinit -INCLUDE "options.h" - -SHELLPROC { - int i; - - for (i = 0; optlist[i].name; i++) - optlist[i].val = 0; - optschanged(); - -} -#endif - - -/* - * Set the shell parameters. - */ - -void -setparam(char **argv) -{ - char **newparam; - char **ap; - int nparam; - - for (nparam = 0 ; argv[nparam] ; nparam++); - ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); - while (*argv) { - *ap++ = savestr(*argv++); - } - *ap = NULL; - freeparam(&shellparam); - shellparam.malloc = 1; - shellparam.nparam = nparam; - shellparam.p = newparam; - shellparam.optnext = NULL; -} - - -/* - * Free the list of positional parameters. - */ - -void -freeparam(volatile struct shparam *param) -{ - char **ap; - - if (param->malloc) { - for (ap = param->p ; *ap ; ap++) - ckfree(*ap); - ckfree(param->p); - } -} - - - -/* - * The shift builtin command. - */ - -int -shiftcmd(int argc, char **argv) -{ - int n; - char **ap1, **ap2; - - n = 1; - if (argc > 1) - n = number(argv[1]); - if (n > shellparam.nparam) - error("can't shift that many"); - INTOFF; - shellparam.nparam -= n; - for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { - if (shellparam.malloc) - ckfree(*ap1); - } - ap2 = shellparam.p; - while ((*ap2++ = *ap1++) != NULL); - shellparam.optnext = NULL; - INTON; - return 0; -} - - - -/* - * The set command builtin. - */ - -int -setcmd(int argc, char **argv) -{ - if (argc == 1) - return showvars(0, 0, 1); - INTOFF; - options(0); - optschanged(); - if (*argptr != NULL) { - setparam(argptr); - } - INTON; - return 0; -} - - -void -getoptsreset(value) - const char *value; -{ - if (number(value) == 1) { - shellparam.optnext = NULL; - shellparam.reset = 1; - } -} - -/* - * The getopts builtin. Shellparam.optnext points to the next argument - * to be processed. Shellparam.optptr points to the next character to - * be processed in the current argument. If shellparam.optnext is NULL, - * then it's the first time getopts has been called. - */ - -int -getoptscmd(int argc, char **argv) -{ - char **optbase; - - if (argc < 3) - error("usage: getopts optstring var [arg]"); - else if (argc == 3) - optbase = shellparam.p; - else - optbase = &argv[3]; - - if (shellparam.reset == 1) { - shellparam.optnext = optbase; - shellparam.optptr = NULL; - shellparam.reset = 0; - } - - return getopts(argv[1], argv[2], optbase, &shellparam.optnext, - &shellparam.optptr); -} - -STATIC int -getopts(char *optstr, char *optvar, char **optfirst, char ***optnext, char **optpptr) -{ - char *p, *q; - char c = '?'; - int done = 0; - int ind = 0; - int err = 0; - char s[12]; - - if ((p = *optpptr) == NULL || *p == '\0') { - /* Current word is done, advance */ - if (*optnext == NULL) - return 1; - p = **optnext; - if (p == NULL || *p != '-' || *++p == '\0') { -atend: - ind = *optnext - optfirst + 1; - *optnext = NULL; - p = NULL; - done = 1; - goto out; - } - (*optnext)++; - if (p[0] == '-' && p[1] == '\0') /* check for "--" */ - goto atend; - } - - c = *p++; - for (q = optstr; *q != c; ) { - if (*q == '\0') { - if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); - } else { - outfmt(&errout, "Illegal option -%c\n", c); - (void) unsetvar("OPTARG", 0); - } - c = '?'; - goto bad; - } - if (*++q == ':') - q++; - } - - if (*++q == ':') { - if (*p == '\0' && (p = **optnext) == NULL) { - if (optstr[0] == ':') { - s[0] = c; - s[1] = '\0'; - err |= setvarsafe("OPTARG", s, 0); - c = ':'; - } else { - outfmt(&errout, "No arg for -%c option\n", c); - (void) unsetvar("OPTARG", 0); - c = '?'; - } - goto bad; - } - - if (p == **optnext) - (*optnext)++; - err |= setvarsafe("OPTARG", p, 0); - p = NULL; - } else - err |= setvarsafe("OPTARG", "", 0); - ind = *optnext - optfirst + 1; - goto out; - -bad: - ind = 1; - *optnext = NULL; - p = NULL; -out: - *optpptr = p; - fmtstr(s, sizeof(s), "%d", ind); - err |= setvarsafe("OPTIND", s, VNOFUNC); - s[0] = c; - s[1] = '\0'; - err |= setvarsafe(optvar, s, 0); - if (err) { - *optnext = NULL; - *optpptr = NULL; - flushall(); - exraise(EXERROR); - } - return done; -} - -/* - * XXX - should get rid of. have all builtins use getopt(3). the - * library getopt must have the BSD extension static variable "optreset" - * otherwise it can't be used within the shell safely. - * - * Standard option processing (a la getopt) for builtin routines. The - * only argument that is passed to nextopt is the option string; the - * other arguments are unnecessary. It return the character, or '\0' on - * end of input. - */ - -int -nextopt(const char *optstring) -{ - char *p; - const char *q; - char c; - - if ((p = optptr) == NULL || *p == '\0') { - p = *argptr; - if (p == NULL || *p != '-' || *++p == '\0') - return '\0'; - argptr++; - if (p[0] == '-' && p[1] == '\0') /* check for "--" */ - return '\0'; - } - c = *p++; - for (q = optstring ; *q != c ; ) { - if (*q == '\0') - error("Illegal option -%c", c); - if (*++q == ':') - q++; - } - if (*++q == ':') { - if (*p == '\0' && (p = *argptr++) == NULL) - error("No arg for -%c option", c); - optionarg = p; - p = NULL; - } - optptr = p; - return c; -} diff --git a/sh/options.h b/sh/options.h deleted file mode 100644 index 4cc7dbec43ae61b2a42a20f93879bb3ff5a96547..0000000000000000000000000000000000000000 --- a/sh/options.h +++ /dev/null @@ -1,131 +0,0 @@ -/* $NetBSD: options.h,v 1.17 2003/08/07 09:05:36 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)options.h 8.2 (Berkeley) 5/4/95 - */ - -struct shparam { - int nparam; /* # of positional parameters (without $0) */ - unsigned char malloc; /* if parameter list dynamically allocated */ - unsigned char reset; /* if getopts has been reset */ - char **p; /* parameter list */ - char **optnext; /* next parameter to be processed by getopts */ - char *optptr; /* used by getopts */ -}; - - -struct optent { - const char *name; /* for set -o <name> */ - const char letter; /* set [+/-]<letter> and $- */ - const char opt_set; /* mutually exclusive option set */ - char val; /* value of <letter>flag */ -}; - -/* Those marked [U] are required by posix, but have no effect! */ - -#ifdef DEFINE_OPTIONS -#define DEF_OPTS(name, letter, opt_set) {name, letter, opt_set, 0}, -struct optent optlist[] = { -#else -#define DEF_OPTS(name, letter, opt_set) -#endif -#define DEF_OPT(name,letter) DEF_OPTS(name, letter, 0) - -DEF_OPT( "errexit", 'e' ) /* exit on error */ -#define eflag optlist[0].val -DEF_OPT( "noglob", 'f' ) /* no pathname expansion */ -#define fflag optlist[1].val -DEF_OPT( "ignoreeof", 'I' ) /* do not exit on EOF */ -#define Iflag optlist[2].val -DEF_OPT( "interactive",'i' ) /* interactive shell */ -#define iflag optlist[3].val -DEF_OPT( "monitor", 'm' ) /* job control */ -#define mflag optlist[4].val -DEF_OPT( "noexec", 'n' ) /* [U] do not exec commands */ -#define nflag optlist[5].val -DEF_OPT( "stdin", 's' ) /* read from stdin */ -#define sflag optlist[6].val -DEF_OPT( "xtrace", 'x' ) /* trace after expansion */ -#define xflag optlist[7].val -DEF_OPT( "verbose", 'v' ) /* trace read input */ -#define vflag optlist[8].val -DEF_OPTS( "vi", 'V', 'V' ) /* vi style editing */ -#define Vflag optlist[9].val -DEF_OPTS( "emacs", 'E', 'V' ) /* emacs style editing */ -#define Eflag optlist[10].val -DEF_OPT( "noclobber", 'C' ) /* do not overwrite files with > */ -#define Cflag optlist[11].val -DEF_OPT( "allexport", 'a' ) /* export all variables */ -#define aflag optlist[12].val -DEF_OPT( "notify", 'b' ) /* [U] report completion of background jobs */ -#define bflag optlist[13].val -DEF_OPT( "nounset", 'u' ) /* error expansion of unset variables */ -#define uflag optlist[14].val -DEF_OPT( "quietprofile", 'q' ) -#define qflag optlist[15].val -DEF_OPT( "nolog", 0 ) /* [U] no functon defs in command history */ -#define nolog optlist[16].val -DEF_OPT( "cdprint", 0 ) /* always print result of cd */ -#define cdprint optlist[17].val -#ifdef DEBUG -DEF_OPT( "debug", 0 ) /* enable debug prints */ -#define debug optlist[18].val -#endif - -#ifdef DEFINE_OPTIONS - { 0, 0, 0, 0 }, -}; -#define NOPTS (sizeof optlist / sizeof optlist[0] - 1) -int sizeof_optlist = sizeof optlist; -#else -extern struct optent optlist[]; -extern int sizeof_optlist; -#endif - - -extern char *minusc; /* argument to -c option */ -extern char *arg0; /* $0 */ -extern struct shparam shellparam; /* $@ */ -extern char **argptr; /* argument list for builtin commands */ -extern char *optionarg; /* set by nextopt */ -extern char *optptr; /* used by nextopt */ - -void procargs(int, char **); -void optschanged(void); -void setparam(char **); -void freeparam(volatile struct shparam *); -int shiftcmd(int, char **); -int setcmd(int, char **); -int getoptscmd(int, char **); -int nextopt(const char *); -void getoptsreset(const char *); diff --git a/sh/output.c b/sh/output.c deleted file mode 100644 index b0e669e25cabe041f8d32ff87eda7fe38f99b40d..0000000000000000000000000000000000000000 --- a/sh/output.c +++ /dev/null @@ -1,516 +0,0 @@ -/* $NetBSD: output.c,v 1.28 2003/08/07 09:05:36 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: output.c,v 1.28 2003/08/07 09:05:36 agc Exp $"); -#endif -#endif /* not lint */ - -/* - * Shell output routines. We use our own output routines because: - * When a builtin command is interrupted we have to discard - * any pending output. - * When a builtin command appears in back quotes, we want to - * save the output of the command in a region obtained - * via malloc, rather than doing a fork and reading the - * output of the command via a pipe. - * Our output routines may be smaller than the stdio routines. - */ - -#include <sys/types.h> /* quad_t */ -#include <sys/param.h> /* BSD4_4 */ -#include <sys/ioctl.h> - -#include <stdio.h> /* defines BUFSIZ */ -#include <string.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> - -#include "shell.h" -#include "syntax.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" - - -#define OUTBUFSIZ BUFSIZ -#define BLOCK_OUT -2 /* output to a fixed block of memory */ -#define MEM_OUT -3 /* output to dynamically allocated memory */ -#define OUTPUT_ERR 01 /* error occurred on output */ - - -struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; -struct output errout = {NULL, 0, NULL, 100, 2, 0}; -struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; -struct output *out1 = &output; -struct output *out2 = &errout; - - - -#ifdef mkinit - -INCLUDE "output.h" -INCLUDE "memalloc.h" - -RESET { - out1 = &output; - out2 = &errout; - if (memout.buf != NULL) { - ckfree(memout.buf); - memout.buf = NULL; - } -} - -#endif - - -#ifdef notdef /* no longer used */ -/* - * Set up an output file to write to memory rather than a file. - */ - -void -open_mem(char *block, int length, struct output *file) -{ - file->nextc = block; - file->nleft = --length; - file->fd = BLOCK_OUT; - file->flags = 0; -} -#endif - - -void -out1str(const char *p) -{ - outstr(p, out1); -} - - -void -out2str(const char *p) -{ - outstr(p, out2); -} - - -void -outstr(const char *p, struct output *file) -{ - while (*p) - outc(*p++, file); - if (file == out2) - flushout(file); -} - - -char out_junk[16]; - - -void -emptyoutbuf(struct output *dest) -{ - int offset; - - if (dest->fd == BLOCK_OUT) { - dest->nextc = out_junk; - dest->nleft = sizeof out_junk; - dest->flags |= OUTPUT_ERR; - } else if (dest->buf == NULL) { - INTOFF; - dest->buf = ckmalloc(dest->bufsize); - dest->nextc = dest->buf; - dest->nleft = dest->bufsize; - INTON; - } else if (dest->fd == MEM_OUT) { - offset = dest->bufsize; - INTOFF; - dest->bufsize <<= 1; - dest->buf = ckrealloc(dest->buf, dest->bufsize); - dest->nleft = dest->bufsize - offset; - dest->nextc = dest->buf + offset; - INTON; - } else { - flushout(dest); - } - dest->nleft--; -} - - -void -flushall(void) -{ - flushout(&output); - flushout(&errout); -} - - -void -flushout(struct output *dest) -{ - - if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0) - return; - if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0) - dest->flags |= OUTPUT_ERR; - dest->nextc = dest->buf; - dest->nleft = dest->bufsize; -} - - -void -freestdout(void) -{ - INTOFF; - if (output.buf) { - ckfree(output.buf); - output.buf = NULL; - output.nleft = 0; - } - INTON; -} - - -void -outfmt(struct output *file, const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - doformat(file, fmt, ap); - va_end(ap); -} - - -void -out1fmt(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - doformat(out1, fmt, ap); - va_end(ap); -} - -void -dprintf(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - doformat(out2, fmt, ap); - va_end(ap); - flushout(out2); -} - -void -fmtstr(char *outbuf, size_t length, const char *fmt, ...) -{ - va_list ap; - struct output strout; - - va_start(ap, fmt); - strout.nextc = outbuf; - strout.nleft = length; - strout.fd = BLOCK_OUT; - strout.flags = 0; - doformat(&strout, fmt, ap); - outc('\0', &strout); - if (strout.flags & OUTPUT_ERR) - outbuf[length - 1] = '\0'; - va_end(ap); -} - -/* - * Formatted output. This routine handles a subset of the printf formats: - * - Formats supported: d, u, o, p, X, s, and c. - * - The x format is also accepted but is treated like X. - * - The l, ll and q modifiers are accepted. - * - The - and # flags are accepted; # only works with the o format. - * - Width and precision may be specified with any format except c. - * - An * may be given for the width or precision. - * - The obsolete practice of preceding the width with a zero to get - * zero padding is not supported; use the precision field. - * - A % may be printed by writing %% in the format string. - */ - -#define TEMPSIZE 24 - -#ifdef BSD4_4 -#define HAVE_VASPRINTF 1 -#endif - -void -doformat(struct output *dest, const char *f, va_list ap) -{ -#if HAVE_VASPRINTF - char *s; - - vasprintf(&s, f, ap); - outstr(s, dest); - free(s); -#else /* !HAVE_VASPRINTF */ - static const char digit[] = "0123456789ABCDEF"; - char c; - char temp[TEMPSIZE]; - int flushleft; - int sharp; - int width; - int prec; - int islong; - int isquad; - char *p; - int sign; -#ifdef BSD4_4 - quad_t l; - u_quad_t num; -#else - long l; - u_long num; -#endif - unsigned base; - int len; - int size; - int pad; - - while ((c = *f++) != '\0') { - if (c != '%') { - outc(c, dest); - continue; - } - flushleft = 0; - sharp = 0; - width = 0; - prec = -1; - islong = 0; - isquad = 0; - for (;;) { - if (*f == '-') - flushleft++; - else if (*f == '#') - sharp++; - else - break; - f++; - } - if (*f == '*') { - width = va_arg(ap, int); - f++; - } else { - while (is_digit(*f)) { - width = 10 * width + digit_val(*f++); - } - } - if (*f == '.') { - if (*++f == '*') { - prec = va_arg(ap, int); - f++; - } else { - prec = 0; - while (is_digit(*f)) { - prec = 10 * prec + digit_val(*f++); - } - } - } - if (*f == 'l') { - f++; - if (*f == 'l') { - isquad++; - f++; - } else - islong++; - } else if (*f == 'q') { - isquad++; - f++; - } - switch (*f) { - case 'd': -#ifdef BSD4_4 - if (isquad) - l = va_arg(ap, quad_t); - else -#endif - if (islong) - l = va_arg(ap, long); - else - l = va_arg(ap, int); - sign = 0; - num = l; - if (l < 0) { - num = -l; - sign = 1; - } - base = 10; - goto number; - case 'u': - base = 10; - goto uns_number; - case 'o': - base = 8; - goto uns_number; - case 'p': - outc('0', dest); - outc('x', dest); - /*FALLTHROUGH*/ - case 'x': - /* we don't implement 'x'; treat like 'X' */ - case 'X': - base = 16; -uns_number: /* an unsigned number */ - sign = 0; -#ifdef BSD4_4 - if (isquad) - num = va_arg(ap, u_quad_t); - else -#endif - if (islong) - num = va_arg(ap, unsigned long); - else - num = va_arg(ap, unsigned int); -number: /* process a number */ - p = temp + TEMPSIZE - 1; - *p = '\0'; - while (num) { - *--p = digit[num % base]; - num /= base; - } - len = (temp + TEMPSIZE - 1) - p; - if (prec < 0) - prec = 1; - if (sharp && *f == 'o' && prec <= len) - prec = len + 1; - pad = 0; - if (width) { - size = len; - if (size < prec) - size = prec; - size += sign; - pad = width - size; - if (flushleft == 0) { - while (--pad >= 0) - outc(' ', dest); - } - } - if (sign) - outc('-', dest); - prec -= len; - while (--prec >= 0) - outc('0', dest); - while (*p) - outc(*p++, dest); - while (--pad >= 0) - outc(' ', dest); - break; - case 's': - p = va_arg(ap, char *); - pad = 0; - if (width) { - len = strlen(p); - if (prec >= 0 && len > prec) - len = prec; - pad = width - len; - if (flushleft == 0) { - while (--pad >= 0) - outc(' ', dest); - } - } - prec++; - while (--prec != 0 && *p) - outc(*p++, dest); - while (--pad >= 0) - outc(' ', dest); - break; - case 'c': - c = va_arg(ap, int); - outc(c, dest); - break; - default: - outc(*f, dest); - break; - } - f++; - } -#endif /* !HAVE_VASPRINTF */ -} - - - -/* - * Version of write which resumes after a signal is caught. - */ - -int -xwrite(int fd, char *buf, int nbytes) -{ - int ntry; - int i; - int n; - - n = nbytes; - ntry = 0; - for (;;) { - i = write(fd, buf, n); - if (i > 0) { - if ((n -= i) <= 0) - return nbytes; - buf += i; - ntry = 0; - } else if (i == 0) { - if (++ntry > 10) - return nbytes - n; - } else if (errno != EINTR) { - return -1; - } - } -} - - -/* - * Version of ioctl that retries after a signal is caught. - * XXX unused function - */ - -int -xioctl(int fd, unsigned long request, char *arg) -{ - int i; - - while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR); - return i; -} diff --git a/sh/output.h b/sh/output.h deleted file mode 100644 index 9a199a0a0f44da858f98ce4b6e786ebd4e8d7302..0000000000000000000000000000000000000000 --- a/sh/output.h +++ /dev/null @@ -1,81 +0,0 @@ -/* $NetBSD: output.h,v 1.17 2003/08/07 09:05:36 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)output.h 8.2 (Berkeley) 5/4/95 - */ - -#ifndef OUTPUT_INCL - -#include <stdarg.h> - -struct output { - char *nextc; - int nleft; - char *buf; - int bufsize; - short fd; - short flags; -}; - -extern struct output output; -extern struct output errout; -extern struct output memout; -extern struct output *out1; -extern struct output *out2; - -void open_mem(char *, int, struct output *); -void out1str(const char *); -void out2str(const char *); -void outstr(const char *, struct output *); -void emptyoutbuf(struct output *); -void flushall(void); -void flushout(struct output *); -void freestdout(void); -void outfmt(struct output *, const char *, ...) - __attribute__((__format__(__printf__,2,3))); -void out1fmt(const char *, ...) - __attribute__((__format__(__printf__,1,2))); -void dprintf(const char *, ...) - __attribute__((__format__(__printf__,1,2))); -void fmtstr(char *, size_t, const char *, ...) - __attribute__((__format__(__printf__,3,4))); -void doformat(struct output *, const char *, va_list); -int xwrite(int, char *, int); -int xioctl(int, unsigned long, char *); - -#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c))) -#define out1c(c) outc(c, out1); -#define out2c(c) outc(c, out2); - -#define OUTPUT_INCL -#endif diff --git a/sh/parser.c b/sh/parser.c deleted file mode 100644 index 67de58e35bc14b350c600d78fe245b16be22f290..0000000000000000000000000000000000000000 --- a/sh/parser.c +++ /dev/null @@ -1,1651 +0,0 @@ -/* $NetBSD: parser.c,v 1.57 2004/06/27 10:27:57 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; -#else -__RCSID("$NetBSD: parser.c,v 1.57 2004/06/27 10:27:57 dsl Exp $"); -#endif -#endif /* not lint */ - -#include <stdlib.h> - -#include "shell.h" -#include "parser.h" -#include "nodes.h" -#include "expand.h" /* defines rmescapes() */ -#include "eval.h" /* defines commandname */ -#include "redir.h" /* defines copyfd() */ -#include "syntax.h" -#include "options.h" -#include "input.h" -#include "output.h" -#include "var.h" -#include "error.h" -#include "memalloc.h" -#include "mystring.h" -#include "alias.h" -#include "show.h" -#ifndef SMALL -#include "myhistedit.h" -#endif - -/* - * Shell command parser. - */ - -#define EOFMARKLEN 79 - -/* values returned by readtoken */ -#include "token.h" - -#define OPENBRACE '{' -#define CLOSEBRACE '}' - - -struct heredoc { - struct heredoc *next; /* next here document in list */ - union node *here; /* redirection node */ - char *eofmark; /* string indicating end of input */ - int striptabs; /* if set, strip leading tabs */ -}; - - - -static int noalias = 0; /* when set, don't handle aliases */ -struct heredoc *heredoclist; /* list of here documents to read */ -int parsebackquote; /* nonzero if we are inside backquotes */ -int doprompt; /* if set, prompt the user */ -int needprompt; /* true if interactive and at start of line */ -int lasttoken; /* last token read */ -MKINIT int tokpushback; /* last token pushed back */ -char *wordtext; /* text of last word returned by readtoken */ -MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ -struct nodelist *backquotelist; -union node *redirnode; -struct heredoc *heredoc; -int quoteflag; /* set if (part of) last token was quoted */ -int startlinno; /* line # where last token started */ - - -STATIC union node *list(int); -STATIC union node *andor(void); -STATIC union node *pipeline(void); -STATIC union node *command(void); -STATIC union node *simplecmd(union node **, union node *); -STATIC union node *makename(void); -STATIC void parsefname(void); -STATIC void parseheredoc(void); -STATIC int peektoken(void); -STATIC int readtoken(void); -STATIC int xxreadtoken(void); -STATIC int readtoken1(int, char const *, char *, int); -STATIC int noexpand(char *); -STATIC void synexpect(int) __attribute__((__noreturn__)); -STATIC void synerror(const char *) __attribute__((__noreturn__)); -STATIC void setprompt(int); - - -/* - * Read and parse a command. Returns NEOF on end of file. (NULL is a - * valid parse tree indicating a blank line.) - */ - -union node * -parsecmd(int interact) -{ - int t; - - tokpushback = 0; - doprompt = interact; - if (doprompt) - setprompt(1); - else - setprompt(0); - needprompt = 0; - t = readtoken(); - if (t == TEOF) - return NEOF; - if (t == TNL) - return NULL; - tokpushback++; - return list(1); -} - - -STATIC union node * -list(int nlflag) -{ - union node *n1, *n2, *n3; - int tok; - - checkkwd = 2; - if (nlflag == 0 && tokendlist[peektoken()]) - return NULL; - n1 = NULL; - for (;;) { - n2 = andor(); - tok = readtoken(); - if (tok == TBACKGND) { - if (n2->type == NCMD || n2->type == NPIPE) { - n2->ncmd.backgnd = 1; - } else if (n2->type == NREDIR) { - n2->type = NBACKGND; - } else { - n3 = (union node *)stalloc(sizeof (struct nredir)); - n3->type = NBACKGND; - n3->nredir.n = n2; - n3->nredir.redirect = NULL; - n2 = n3; - } - } - if (n1 == NULL) { - n1 = n2; - } - else { - n3 = (union node *)stalloc(sizeof (struct nbinary)); - n3->type = NSEMI; - n3->nbinary.ch1 = n1; - n3->nbinary.ch2 = n2; - n1 = n3; - } - switch (tok) { - case TBACKGND: - case TSEMI: - tok = readtoken(); - /* fall through */ - case TNL: - if (tok == TNL) { - parseheredoc(); - if (nlflag) - return n1; - } else { - tokpushback++; - } - checkkwd = 2; - if (tokendlist[peektoken()]) - return n1; - break; - case TEOF: - if (heredoclist) - parseheredoc(); - else - pungetc(); /* push back EOF on input */ - return n1; - default: - if (nlflag) - synexpect(-1); - tokpushback++; - return n1; - } - } -} - - - -STATIC union node * -andor(void) -{ - union node *n1, *n2, *n3; - int t; - - n1 = pipeline(); - for (;;) { - if ((t = readtoken()) == TAND) { - t = NAND; - } else if (t == TOR) { - t = NOR; - } else { - tokpushback++; - return n1; - } - n2 = pipeline(); - n3 = (union node *)stalloc(sizeof (struct nbinary)); - n3->type = t; - n3->nbinary.ch1 = n1; - n3->nbinary.ch2 = n2; - n1 = n3; - } -} - - - -STATIC union node * -pipeline(void) -{ - union node *n1, *n2, *pipenode; - struct nodelist *lp, *prev; - int negate; - - negate = 0; - TRACE(("pipeline: entered\n")); - while (readtoken() == TNOT) - negate = !negate; - tokpushback++; - n1 = command(); - if (readtoken() == TPIPE) { - pipenode = (union node *)stalloc(sizeof (struct npipe)); - pipenode->type = NPIPE; - pipenode->npipe.backgnd = 0; - lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); - pipenode->npipe.cmdlist = lp; - lp->n = n1; - do { - prev = lp; - lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); - lp->n = command(); - prev->next = lp; - } while (readtoken() == TPIPE); - lp->next = NULL; - n1 = pipenode; - } - tokpushback++; - if (negate) { - n2 = (union node *)stalloc(sizeof (struct nnot)); - n2->type = NNOT; - n2->nnot.com = n1; - return n2; - } else - return n1; -} - - - -STATIC union node * -command(void) -{ - union node *n1, *n2; - union node *ap, **app; - union node *cp, **cpp; - union node *redir, **rpp; - int t, negate = 0; - - checkkwd = 2; - redir = NULL; - n1 = NULL; - rpp = &redir; - - /* Check for redirection which may precede command */ - while (readtoken() == TREDIR) { - *rpp = n2 = redirnode; - rpp = &n2->nfile.next; - parsefname(); - } - tokpushback++; - - while (readtoken() == TNOT) { - TRACE(("command: TNOT recognized\n")); - negate = !negate; - } - tokpushback++; - - switch (readtoken()) { - case TIF: - n1 = (union node *)stalloc(sizeof (struct nif)); - n1->type = NIF; - n1->nif.test = list(0); - if (readtoken() != TTHEN) - synexpect(TTHEN); - n1->nif.ifpart = list(0); - n2 = n1; - while (readtoken() == TELIF) { - n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); - n2 = n2->nif.elsepart; - n2->type = NIF; - n2->nif.test = list(0); - if (readtoken() != TTHEN) - synexpect(TTHEN); - n2->nif.ifpart = list(0); - } - if (lasttoken == TELSE) - n2->nif.elsepart = list(0); - else { - n2->nif.elsepart = NULL; - tokpushback++; - } - if (readtoken() != TFI) - synexpect(TFI); - checkkwd = 1; - break; - case TWHILE: - case TUNTIL: { - int got; - n1 = (union node *)stalloc(sizeof (struct nbinary)); - n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; - n1->nbinary.ch1 = list(0); - if ((got=readtoken()) != TDO) { -TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); - synexpect(TDO); - } - n1->nbinary.ch2 = list(0); - if (readtoken() != TDONE) - synexpect(TDONE); - checkkwd = 1; - break; - } - case TFOR: - if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) - synerror("Bad for loop variable"); - n1 = (union node *)stalloc(sizeof (struct nfor)); - n1->type = NFOR; - n1->nfor.var = wordtext; - if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) { - app = ≈ - while (readtoken() == TWORD) { - n2 = (union node *)stalloc(sizeof (struct narg)); - n2->type = NARG; - n2->narg.text = wordtext; - n2->narg.backquote = backquotelist; - *app = n2; - app = &n2->narg.next; - } - *app = NULL; - n1->nfor.args = ap; - if (lasttoken != TNL && lasttoken != TSEMI) - synexpect(-1); - } else { - static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, - '@', '=', '\0'}; - n2 = (union node *)stalloc(sizeof (struct narg)); - n2->type = NARG; - n2->narg.text = argvars; - n2->narg.backquote = NULL; - n2->narg.next = NULL; - n1->nfor.args = n2; - /* - * Newline or semicolon here is optional (but note - * that the original Bourne shell only allowed NL). - */ - if (lasttoken != TNL && lasttoken != TSEMI) - tokpushback++; - } - checkkwd = 2; - if ((t = readtoken()) == TDO) - t = TDONE; - else if (t == TBEGIN) - t = TEND; - else - synexpect(-1); - n1->nfor.body = list(0); - if (readtoken() != t) - synexpect(t); - checkkwd = 1; - break; - case TCASE: - n1 = (union node *)stalloc(sizeof (struct ncase)); - n1->type = NCASE; - if (readtoken() != TWORD) - synexpect(TWORD); - n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); - n2->type = NARG; - n2->narg.text = wordtext; - n2->narg.backquote = backquotelist; - n2->narg.next = NULL; - while (readtoken() == TNL); - if (lasttoken != TWORD || ! equal(wordtext, "in")) - synerror("expecting \"in\""); - cpp = &n1->ncase.cases; - noalias = 1; - checkkwd = 2, readtoken(); - do { - *cpp = cp = (union node *)stalloc(sizeof (struct nclist)); - cp->type = NCLIST; - app = &cp->nclist.pattern; - for (;;) { - *app = ap = (union node *)stalloc(sizeof (struct narg)); - ap->type = NARG; - ap->narg.text = wordtext; - ap->narg.backquote = backquotelist; - if (checkkwd = 2, readtoken() != TPIPE) - break; - app = &ap->narg.next; - readtoken(); - } - ap->narg.next = NULL; - noalias = 0; - if (lasttoken != TRP) { - synexpect(TRP); - } - cp->nclist.body = list(0); - - checkkwd = 2; - if ((t = readtoken()) != TESAC) { - if (t != TENDCASE) { - noalias = 0; - synexpect(TENDCASE); - } else { - noalias = 1; - checkkwd = 2; - readtoken(); - } - } - cpp = &cp->nclist.next; - } while(lasttoken != TESAC); - noalias = 0; - *cpp = NULL; - checkkwd = 1; - break; - case TLP: - n1 = (union node *)stalloc(sizeof (struct nredir)); - n1->type = NSUBSHELL; - n1->nredir.n = list(0); - n1->nredir.redirect = NULL; - if (readtoken() != TRP) - synexpect(TRP); - checkkwd = 1; - break; - case TBEGIN: - n1 = list(0); - if (readtoken() != TEND) - synexpect(TEND); - checkkwd = 1; - break; - /* Handle an empty command like other simple commands. */ - case TSEMI: - /* - * An empty command before a ; doesn't make much sense, and - * should certainly be disallowed in the case of `if ;'. - */ - if (!redir) - synexpect(-1); - case TAND: - case TOR: - case TNL: - case TEOF: - case TWORD: - case TRP: - tokpushback++; - n1 = simplecmd(rpp, redir); - goto checkneg; - default: - synexpect(-1); - /* NOTREACHED */ - } - - /* Now check for redirection which may follow command */ - while (readtoken() == TREDIR) { - *rpp = n2 = redirnode; - rpp = &n2->nfile.next; - parsefname(); - } - tokpushback++; - *rpp = NULL; - if (redir) { - if (n1->type != NSUBSHELL) { - n2 = (union node *)stalloc(sizeof (struct nredir)); - n2->type = NREDIR; - n2->nredir.n = n1; - n1 = n2; - } - n1->nredir.redirect = redir; - } - -checkneg: - if (negate) { - n2 = (union node *)stalloc(sizeof (struct nnot)); - n2->type = NNOT; - n2->nnot.com = n1; - return n2; - } - else - return n1; -} - - -STATIC union node * -simplecmd(union node **rpp, union node *redir) -{ - union node *args, **app; - union node **orig_rpp = rpp; - union node *n = NULL, *n2; - int negate = 0; - - /* If we don't have any redirections already, then we must reset */ - /* rpp to be the address of the local redir variable. */ - if (redir == 0) - rpp = &redir; - - args = NULL; - app = &args; - /* - * We save the incoming value, because we need this for shell - * functions. There can not be a redirect or an argument between - * the function name and the open parenthesis. - */ - orig_rpp = rpp; - - while (readtoken() == TNOT) { - TRACE(("command: TNOT recognized\n")); - negate = !negate; - } - tokpushback++; - - for (;;) { - if (readtoken() == TWORD) { - n = (union node *)stalloc(sizeof (struct narg)); - n->type = NARG; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - *app = n; - app = &n->narg.next; - } else if (lasttoken == TREDIR) { - *rpp = n = redirnode; - rpp = &n->nfile.next; - parsefname(); /* read name of redirection file */ - } else if (lasttoken == TLP && app == &args->narg.next - && rpp == orig_rpp) { - /* We have a function */ - if (readtoken() != TRP) - synexpect(TRP); -#ifdef notdef - if (! goodname(n->narg.text)) - synerror("Bad function name"); -#endif - n->type = NDEFUN; - n->narg.next = command(); - goto checkneg; - } else { - tokpushback++; - break; - } - } - *app = NULL; - *rpp = NULL; - n = (union node *)stalloc(sizeof (struct ncmd)); - n->type = NCMD; - n->ncmd.backgnd = 0; - n->ncmd.args = args; - n->ncmd.redirect = redir; - -checkneg: - if (negate) { - n2 = (union node *)stalloc(sizeof (struct nnot)); - n2->type = NNOT; - n2->nnot.com = n; - return n2; - } - else - return n; -} - -STATIC union node * -makename(void) -{ - union node *n; - - n = (union node *)stalloc(sizeof (struct narg)); - n->type = NARG; - n->narg.next = NULL; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - return n; -} - -void fixredir(union node *n, const char *text, int err) - { - TRACE(("Fix redir %s %d\n", text, err)); - if (!err) - n->ndup.vname = NULL; - - if (is_digit(text[0]) && text[1] == '\0') - n->ndup.dupfd = digit_val(text[0]); - else if (text[0] == '-' && text[1] == '\0') - n->ndup.dupfd = -1; - else { - - if (err) - synerror("Bad fd number"); - else - n->ndup.vname = makename(); - } -} - - -STATIC void -parsefname(void) -{ - union node *n = redirnode; - - if (readtoken() != TWORD) - synexpect(-1); - if (n->type == NHERE) { - struct heredoc *here = heredoc; - struct heredoc *p; - int i; - - if (quoteflag == 0) - n->type = NXHERE; - TRACE(("Here document %d\n", n->type)); - if (here->striptabs) { - while (*wordtext == '\t') - wordtext++; - } - if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) - synerror("Illegal eof marker for << redirection"); - rmescapes(wordtext); - here->eofmark = wordtext; - here->next = NULL; - if (heredoclist == NULL) - heredoclist = here; - else { - for (p = heredoclist ; p->next ; p = p->next); - p->next = here; - } - } else if (n->type == NTOFD || n->type == NFROMFD) { - fixredir(n, wordtext, 0); - } else { - n->nfile.fname = makename(); - } -} - - -/* - * Input any here documents. - */ - -STATIC void -parseheredoc(void) -{ - struct heredoc *here; - union node *n; - - while (heredoclist) { - here = heredoclist; - heredoclist = here->next; - if (needprompt) { - setprompt(2); - needprompt = 0; - } - readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, - here->eofmark, here->striptabs); - n = (union node *)stalloc(sizeof (struct narg)); - n->narg.type = NARG; - n->narg.next = NULL; - n->narg.text = wordtext; - n->narg.backquote = backquotelist; - here->here->nhere.doc = n; - } -} - -STATIC int -peektoken(void) -{ - int t; - - t = readtoken(); - tokpushback++; - return (t); -} - -STATIC int -readtoken(void) -{ - int t; - int savecheckkwd = checkkwd; -#ifdef DEBUG - int alreadyseen = tokpushback; -#endif - struct alias *ap; - - top: - t = xxreadtoken(); - - if (checkkwd) { - /* - * eat newlines - */ - if (checkkwd == 2) { - checkkwd = 0; - while (t == TNL) { - parseheredoc(); - t = xxreadtoken(); - } - } else - checkkwd = 0; - /* - * check for keywords and aliases - */ - if (t == TWORD && !quoteflag) - { - const char *const *pp; - - for (pp = parsekwd; *pp; pp++) { - if (**pp == *wordtext && equal(*pp, wordtext)) - { - lasttoken = t = pp - - parsekwd + KWDOFFSET; - TRACE(("keyword %s recognized\n", tokname[t])); - goto out; - } - } - if(!noalias && - (ap = lookupalias(wordtext, 1)) != NULL) { - pushstring(ap->val, strlen(ap->val), ap); - checkkwd = savecheckkwd; - goto top; - } - } -out: - checkkwd = (t == TNOT) ? savecheckkwd : 0; - } -#ifdef DEBUG - if (!alreadyseen) - TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); - else - TRACE(("reread token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); -#endif - return (t); -} - - -/* - * Read the next input token. - * If the token is a word, we set backquotelist to the list of cmds in - * backquotes. We set quoteflag to true if any part of the word was - * quoted. - * If the token is TREDIR, then we set redirnode to a structure containing - * the redirection. - * In all cases, the variable startlinno is set to the number of the line - * on which the token starts. - * - * [Change comment: here documents and internal procedures] - * [Readtoken shouldn't have any arguments. Perhaps we should make the - * word parsing code into a separate routine. In this case, readtoken - * doesn't need to have any internal procedures, but parseword does. - * We could also make parseoperator in essence the main routine, and - * have parseword (readtoken1?) handle both words and redirection.] - */ - -#define RETURN(token) return lasttoken = token - -STATIC int -xxreadtoken(void) -{ - int c; - - if (tokpushback) { - tokpushback = 0; - return lasttoken; - } - if (needprompt) { - setprompt(2); - needprompt = 0; - } - startlinno = plinno; - for (;;) { /* until token or start of word found */ - c = pgetc_macro(); - if (c == ' ' || c == '\t') - continue; /* quick check for white space first */ - switch (c) { - case ' ': case '\t': - continue; - case '#': - while ((c = pgetc()) != '\n' && c != PEOF); - pungetc(); - continue; - case '\\': - if (pgetc() == '\n') { - startlinno = ++plinno; - if (doprompt) - setprompt(2); - else - setprompt(0); - continue; - } - pungetc(); - goto breakloop; - case '\n': - plinno++; - needprompt = doprompt; - RETURN(TNL); - case PEOF: - RETURN(TEOF); - case '&': - if (pgetc() == '&') - RETURN(TAND); - pungetc(); - RETURN(TBACKGND); - case '|': - if (pgetc() == '|') - RETURN(TOR); - pungetc(); - RETURN(TPIPE); - case ';': - if (pgetc() == ';') - RETURN(TENDCASE); - pungetc(); - RETURN(TSEMI); - case '(': - RETURN(TLP); - case ')': - RETURN(TRP); - default: - goto breakloop; - } - } -breakloop: - return readtoken1(c, BASESYNTAX, (char *)NULL, 0); -#undef RETURN -} - - - -/* - * If eofmark is NULL, read a word or a redirection symbol. If eofmark - * is not NULL, read a here document. In the latter case, eofmark is the - * word which marks the end of the document and striptabs is true if - * leading tabs should be stripped from the document. The argument firstc - * is the first character of the input token or document. - * - * Because C does not have internal subroutines, I have simulated them - * using goto's to implement the subroutine linkage. The following macros - * will run code that appears at the end of readtoken1. - */ - -#define CHECKEND() {goto checkend; checkend_return:;} -#define PARSEREDIR() {goto parseredir; parseredir_return:;} -#define PARSESUB() {goto parsesub; parsesub_return:;} -#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;} -#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;} -#define PARSEARITH() {goto parsearith; parsearith_return:;} - -/* - * Keep track of nested doublequotes in dblquote and doublequotep. - * We use dblquote for the first 32 levels, and we expand to a malloc'ed - * region for levels above that. Usually we never need to malloc. - * This code assumes that an int is 32 bits. We don't use uint32_t, - * because the rest of the code does not. - */ -#define ISDBLQUOTE() ((varnest < 32) ? (dblquote & (1 << varnest)) : \ - (dblquotep[(varnest / 32) - 1] & (1 << (varnest % 32)))) - -#define SETDBLQUOTE() \ - if (varnest < 32) \ - dblquote |= (1 << varnest); \ - else \ - dblquotep[(varnest / 32) - 1] |= (1 << (varnest % 32)) - -#define CLRDBLQUOTE() \ - if (varnest < 32) \ - dblquote &= ~(1 << varnest); \ - else \ - dblquotep[(varnest / 32) - 1] &= ~(1 << (varnest % 32)) - -STATIC int -readtoken1(int firstc, char const *syntax, char *eofmark, int striptabs) -{ - int c = firstc; - char *out; - int len; - char line[EOFMARKLEN + 1]; - struct nodelist *bqlist; - int quotef; - int *dblquotep = NULL; - size_t maxnest = 32; - int dblquote; - int varnest; /* levels of variables expansion */ - int arinest; /* levels of arithmetic expansion */ - int parenlevel; /* levels of parens in arithmetic */ - int oldstyle; - char const *prevsyntax = NULL; /* syntax before arithmetic */ -#if __GNUC__ - /* Avoid longjmp clobbering */ - (void) &maxnest; - (void) &dblquotep; - (void) &out; - (void) "ef; - (void) &dblquote; - (void) &varnest; - (void) &arinest; - (void) &parenlevel; - (void) &oldstyle; - (void) &prevsyntax; - (void) &syntax; -#endif - - startlinno = plinno; - dblquote = 0; - varnest = 0; - if (syntax == DQSYNTAX) { - SETDBLQUOTE(); - } - quotef = 0; - bqlist = NULL; - arinest = 0; - parenlevel = 0; - - STARTSTACKSTR(out); - loop: { /* for each line, until end of word */ -#if ATTY - if (c == '\034' && doprompt - && attyset() && ! equal(termval(), "emacs")) { - attyline(); - if (syntax == BASESYNTAX) - return readtoken(); - c = pgetc(); - goto loop; - } -#endif - CHECKEND(); /* set c to PEOF if at end of here document */ - for (;;) { /* until end of line or end of word */ - CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */ - switch(syntax[c]) { - case CNL: /* '\n' */ - if (syntax == BASESYNTAX) - goto endword; /* exit outer loop */ - USTPUTC(c, out); - plinno++; - if (doprompt) - setprompt(2); - else - setprompt(0); - c = pgetc(); - goto loop; /* continue outer loop */ - case CWORD: - USTPUTC(c, out); - break; - case CCTL: - if (eofmark == NULL || ISDBLQUOTE()) - USTPUTC(CTLESC, out); - USTPUTC(c, out); - break; - case CBACK: /* backslash */ - c = pgetc(); - if (c == PEOF) { - USTPUTC('\\', out); - pungetc(); - break; - } - if (c == '\n') { - if (doprompt) - setprompt(2); - else - setprompt(0); - break; - } - quotef = 1; - if (ISDBLQUOTE() && c != '\\' && - c != '`' && c != '$' && - (c != '"' || eofmark != NULL)) - USTPUTC('\\', out); - if (SQSYNTAX[c] == CCTL) - USTPUTC(CTLESC, out); - else if (eofmark == NULL) { - USTPUTC(CTLQUOTEMARK, out); - USTPUTC(c, out); - if (varnest != 0) - USTPUTC(CTLQUOTEEND, out); - break; - } - USTPUTC(c, out); - break; - case CSQUOTE: - if (syntax != SQSYNTAX) { - if (eofmark == NULL) - USTPUTC(CTLQUOTEMARK, out); - quotef = 1; - syntax = SQSYNTAX; - break; - } - if (eofmark != NULL && arinest == 0 && - varnest == 0) { - /* Ignore inside quoted here document */ - USTPUTC(c, out); - break; - } - /* End of single quotes... */ - if (arinest) - syntax = ARISYNTAX; - else { - syntax = BASESYNTAX; - if (varnest != 0) - USTPUTC(CTLQUOTEEND, out); - } - break; - case CDQUOTE: - if (eofmark != NULL && arinest == 0 && - varnest == 0) { - /* Ignore inside here document */ - USTPUTC(c, out); - break; - } - quotef = 1; - if (arinest) { - if (ISDBLQUOTE()) { - syntax = ARISYNTAX; - CLRDBLQUOTE(); - } else { - syntax = DQSYNTAX; - SETDBLQUOTE(); - USTPUTC(CTLQUOTEMARK, out); - } - break; - } - if (eofmark != NULL) - break; - if (ISDBLQUOTE()) { - if (varnest != 0) - USTPUTC(CTLQUOTEEND, out); - syntax = BASESYNTAX; - CLRDBLQUOTE(); - } else { - syntax = DQSYNTAX; - SETDBLQUOTE(); - USTPUTC(CTLQUOTEMARK, out); - } - break; - case CVAR: /* '$' */ - PARSESUB(); /* parse substitution */ - break; - case CENDVAR: /* CLOSEBRACE */ - if (varnest > 0 && !ISDBLQUOTE()) { - varnest--; - USTPUTC(CTLENDVAR, out); - } else { - USTPUTC(c, out); - } - break; - case CLP: /* '(' in arithmetic */ - parenlevel++; - USTPUTC(c, out); - break; - case CRP: /* ')' in arithmetic */ - if (parenlevel > 0) { - USTPUTC(c, out); - --parenlevel; - } else { - if (pgetc() == ')') { - if (--arinest == 0) { - USTPUTC(CTLENDARI, out); - syntax = prevsyntax; - if (syntax == DQSYNTAX) - SETDBLQUOTE(); - else - CLRDBLQUOTE(); - } else - USTPUTC(')', out); - } else { - /* - * unbalanced parens - * (don't 2nd guess - no error) - */ - pungetc(); - USTPUTC(')', out); - } - } - break; - case CBQUOTE: /* '`' */ - PARSEBACKQOLD(); - break; - case CEOF: - goto endword; /* exit outer loop */ - default: - if (varnest == 0) - goto endword; /* exit outer loop */ - USTPUTC(c, out); - } - c = pgetc_macro(); - } - } -endword: - if (syntax == ARISYNTAX) - synerror("Missing '))'"); - if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) - synerror("Unterminated quoted string"); - if (varnest != 0) { - startlinno = plinno; - /* { */ - synerror("Missing '}'"); - } - USTPUTC('\0', out); - len = out - stackblock(); - out = stackblock(); - if (eofmark == NULL) { - if ((c == '>' || c == '<') - && quotef == 0 - && len <= 2 - && (*out == '\0' || is_digit(*out))) { - PARSEREDIR(); - return lasttoken = TREDIR; - } else { - pungetc(); - } - } - quoteflag = quotef; - backquotelist = bqlist; - grabstackblock(len); - wordtext = out; - if (dblquotep != NULL) - ckfree(dblquotep); - return lasttoken = TWORD; -/* end of readtoken routine */ - - - -/* - * Check to see whether we are at the end of the here document. When this - * is called, c is set to the first character of the next input line. If - * we are at the end of the here document, this routine sets the c to PEOF. - */ - -checkend: { - if (eofmark) { - if (striptabs) { - while (c == '\t') - c = pgetc(); - } - if (c == *eofmark) { - if (pfgets(line, sizeof line) != NULL) { - char *p, *q; - - p = line; - for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); - if (*p == '\n' && *q == '\0') { - c = PEOF; - plinno++; - needprompt = doprompt; - } else { - pushstring(line, strlen(line), NULL); - } - } - } - } - goto checkend_return; -} - - -/* - * Parse a redirection operator. The variable "out" points to a string - * specifying the fd to be redirected. The variable "c" contains the - * first character of the redirection operator. - */ - -parseredir: { - char fd = *out; - union node *np; - - np = (union node *)stalloc(sizeof (struct nfile)); - if (c == '>') { - np->nfile.fd = 1; - c = pgetc(); - if (c == '>') - np->type = NAPPEND; - else if (c == '|') - np->type = NCLOBBER; - else if (c == '&') - np->type = NTOFD; - else { - np->type = NTO; - pungetc(); - } - } else { /* c == '<' */ - np->nfile.fd = 0; - switch (c = pgetc()) { - case '<': - if (sizeof (struct nfile) != sizeof (struct nhere)) { - np = (union node *)stalloc(sizeof (struct nhere)); - np->nfile.fd = 0; - } - np->type = NHERE; - heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); - heredoc->here = np; - if ((c = pgetc()) == '-') { - heredoc->striptabs = 1; - } else { - heredoc->striptabs = 0; - pungetc(); - } - break; - - case '&': - np->type = NFROMFD; - break; - - case '>': - np->type = NFROMTO; - break; - - default: - np->type = NFROM; - pungetc(); - break; - } - } - if (fd != '\0') - np->nfile.fd = digit_val(fd); - redirnode = np; - goto parseredir_return; -} - - -/* - * Parse a substitution. At this point, we have read the dollar sign - * and nothing else. - */ - -parsesub: { - int subtype; - int typeloc; - int flags; - char *p; - static const char types[] = "}-+?="; - - c = pgetc(); - if (c != '(' && c != OPENBRACE && !is_name(c) && !is_special(c)) { - USTPUTC('$', out); - pungetc(); - } else if (c == '(') { /* $(command) or $((arith)) */ - if (pgetc() == '(') { - PARSEARITH(); - } else { - pungetc(); - PARSEBACKQNEW(); - } - } else { - USTPUTC(CTLVAR, out); - typeloc = out - stackblock(); - USTPUTC(VSNORMAL, out); - subtype = VSNORMAL; - if (c == OPENBRACE) { - c = pgetc(); - if (c == '#') { - if ((c = pgetc()) == CLOSEBRACE) - c = '#'; - else - subtype = VSLENGTH; - } - else - subtype = 0; - } - if (is_name(c)) { - do { - STPUTC(c, out); - c = pgetc(); - } while (is_in_name(c)); - } else if (is_digit(c)) { - do { - USTPUTC(c, out); - c = pgetc(); - } while (is_digit(c)); - } - else if (is_special(c)) { - USTPUTC(c, out); - c = pgetc(); - } - else -badsub: synerror("Bad substitution"); - - STPUTC('=', out); - flags = 0; - if (subtype == 0) { - switch (c) { - case ':': - flags = VSNUL; - c = pgetc(); - /*FALLTHROUGH*/ - default: - p = strchr(types, c); - if (p == NULL) - goto badsub; - subtype = p - types + VSNORMAL; - break; - case '%': - case '#': - { - int cc = c; - subtype = c == '#' ? VSTRIMLEFT : - VSTRIMRIGHT; - c = pgetc(); - if (c == cc) - subtype++; - else - pungetc(); - break; - } - } - } else { - pungetc(); - } - if (ISDBLQUOTE() || arinest) - flags |= VSQUOTE; - *(stackblock() + typeloc) = subtype | flags; - if (subtype != VSNORMAL) { - varnest++; - if (varnest >= maxnest) { - dblquotep = ckrealloc(dblquotep, maxnest / 8); - dblquotep[(maxnest / 32) - 1] = 0; - maxnest += 32; - } - } - } - goto parsesub_return; -} - - -/* - * Called to parse command substitutions. Newstyle is set if the command - * is enclosed inside $(...); nlpp is a pointer to the head of the linked - * list of commands (passed by reference), and savelen is the number of - * characters on the top of the stack which must be preserved. - */ - -parsebackq: { - struct nodelist **nlpp; - int savepbq; - union node *n; - char *volatile str; - struct jmploc jmploc; - struct jmploc *volatile savehandler; - int savelen; - int saveprompt; -#ifdef __GNUC__ - (void) &saveprompt; -#endif - - savepbq = parsebackquote; - if (setjmp(jmploc.loc)) { - if (str) - ckfree(str); - parsebackquote = 0; - handler = savehandler; - longjmp(handler->loc, 1); - } - INTOFF; - str = NULL; - savelen = out - stackblock(); - if (savelen > 0) { - str = ckmalloc(savelen); - memcpy(str, stackblock(), savelen); - } - savehandler = handler; - handler = &jmploc; - INTON; - if (oldstyle) { - /* We must read until the closing backquote, giving special - treatment to some slashes, and then push the string and - reread it as input, interpreting it normally. */ - char *pout; - int pc; - int psavelen; - char *pstr; - - - STARTSTACKSTR(pout); - for (;;) { - if (needprompt) { - setprompt(2); - needprompt = 0; - } - switch (pc = pgetc()) { - case '`': - goto done; - - case '\\': - if ((pc = pgetc()) == '\n') { - plinno++; - if (doprompt) - setprompt(2); - else - setprompt(0); - /* - * If eating a newline, avoid putting - * the newline into the new character - * stream (via the STPUTC after the - * switch). - */ - continue; - } - if (pc != '\\' && pc != '`' && pc != '$' - && (!ISDBLQUOTE() || pc != '"')) - STPUTC('\\', pout); - break; - - case '\n': - plinno++; - needprompt = doprompt; - break; - - case PEOF: - startlinno = plinno; - synerror("EOF in backquote substitution"); - break; - - default: - break; - } - STPUTC(pc, pout); - } -done: - STPUTC('\0', pout); - psavelen = pout - stackblock(); - if (psavelen > 0) { - pstr = grabstackstr(pout); - setinputstring(pstr, 1); - } - } - nlpp = &bqlist; - while (*nlpp) - nlpp = &(*nlpp)->next; - *nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); - (*nlpp)->next = NULL; - parsebackquote = oldstyle; - - if (oldstyle) { - saveprompt = doprompt; - doprompt = 0; - } - - n = list(0); - - if (oldstyle) - doprompt = saveprompt; - else { - if (readtoken() != TRP) - synexpect(TRP); - } - - (*nlpp)->n = n; - if (oldstyle) { - /* - * Start reading from old file again, ignoring any pushed back - * tokens left from the backquote parsing - */ - popfile(); - tokpushback = 0; - } - while (stackblocksize() <= savelen) - growstackblock(); - STARTSTACKSTR(out); - if (str) { - memcpy(out, str, savelen); - STADJUST(savelen, out); - INTOFF; - ckfree(str); - str = NULL; - INTON; - } - parsebackquote = savepbq; - handler = savehandler; - if (arinest || ISDBLQUOTE()) - USTPUTC(CTLBACKQ | CTLQUOTE, out); - else - USTPUTC(CTLBACKQ, out); - if (oldstyle) - goto parsebackq_oldreturn; - else - goto parsebackq_newreturn; -} - -/* - * Parse an arithmetic expansion (indicate start of one and set state) - */ -parsearith: { - - if (++arinest == 1) { - prevsyntax = syntax; - syntax = ARISYNTAX; - USTPUTC(CTLARI, out); - if (ISDBLQUOTE()) - USTPUTC('"',out); - else - USTPUTC(' ',out); - } else { - /* - * we collapse embedded arithmetic expansion to - * parenthesis, which should be equivalent - */ - USTPUTC('(', out); - } - goto parsearith_return; -} - -} /* end of readtoken */ - - - -#ifdef mkinit -RESET { - tokpushback = 0; - checkkwd = 0; -} -#endif - -/* - * Returns true if the text contains nothing to expand (no dollar signs - * or backquotes). - */ - -STATIC int -noexpand(char *text) -{ - char *p; - char c; - - p = text; - while ((c = *p++) != '\0') { - if (c == CTLQUOTEMARK) - continue; - if (c == CTLESC) - p++; - else if (BASESYNTAX[(int)c] == CCTL) - return 0; - } - return 1; -} - - -/* - * Return true if the argument is a legal variable name (a letter or - * underscore followed by zero or more letters, underscores, and digits). - */ - -int -goodname(char *name) - { - char *p; - - p = name; - if (! is_name(*p)) - return 0; - while (*++p) { - if (! is_in_name(*p)) - return 0; - } - return 1; -} - - -/* - * Called when an unexpected token is read during the parse. The argument - * is the token that is expected, or -1 if more than one type of token can - * occur at this point. - */ - -STATIC void -synexpect(int token) -{ - char msg[64]; - - if (token >= 0) { - fmtstr(msg, 64, "%s unexpected (expecting %s)", - tokname[lasttoken], tokname[token]); - } else { - fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); - } - synerror(msg); - /* NOTREACHED */ -} - - -STATIC void -synerror(const char *msg) -{ - if (commandname) - outfmt(&errout, "%s: %d: ", commandname, startlinno); - outfmt(&errout, "Syntax error: %s\n", msg); - error((char *)NULL); - /* NOTREACHED */ -} - -STATIC void -setprompt(int which) -{ - whichprompt = which; - -#ifdef WITH_HISTORY - if (!el) -#endif - out2str(getprompt(NULL)); -} - -/* - * called by editline -- any expansions to the prompt - * should be added here. - */ -const char * -getprompt(void *unused) - { - switch (whichprompt) { - case 0: - return ""; - case 1: - return ps1val(); - case 2: - return ps2val(); - default: - return "<internal prompt error>"; - } -} diff --git a/sh/parser.h b/sh/parser.h deleted file mode 100644 index b343c71cfff576d78faddf12febc47b9296d7f90..0000000000000000000000000000000000000000 --- a/sh/parser.h +++ /dev/null @@ -1,82 +0,0 @@ -/* $NetBSD: parser.h,v 1.17 2004/06/26 22:09:49 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)parser.h 8.3 (Berkeley) 5/4/95 - */ - -/* control characters in argument strings */ -#define CTL_FIRST '\201' /* first 'special' character */ -#define CTLESC '\201' /* escape next character */ -#define CTLVAR '\202' /* variable defn */ -#define CTLENDVAR '\203' -#define CTLBACKQ '\204' -#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */ -/* CTLBACKQ | CTLQUOTE == '\205' */ -#define CTLARI '\206' /* arithmetic expression */ -#define CTLENDARI '\207' -#define CTLQUOTEMARK '\210' -#define CTLQUOTEEND '\211' /* only inside ${...} */ -#define CTL_LAST '\211' /* last 'special' character */ - -/* variable substitution byte (follows CTLVAR) */ -#define VSTYPE 0x0f /* type of variable substitution */ -#define VSNUL 0x10 /* colon--treat the empty string as unset */ -#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ - -/* values of VSTYPE field */ -#define VSNORMAL 0x1 /* normal variable: $var or ${var} */ -#define VSMINUS 0x2 /* ${var-text} */ -#define VSPLUS 0x3 /* ${var+text} */ -#define VSQUESTION 0x4 /* ${var?message} */ -#define VSASSIGN 0x5 /* ${var=text} */ -#define VSTRIMLEFT 0x6 /* ${var#pattern} */ -#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ -#define VSTRIMRIGHT 0x8 /* ${var%pattern} */ -#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ -#define VSLENGTH 0xa /* ${#var} */ - - -/* - * NEOF is returned by parsecmd when it encounters an end of file. It - * must be distinct from NULL, so we use the address of a variable that - * happens to be handy. - */ -extern int tokpushback; -#define NEOF ((union node *)&tokpushback) -extern int whichprompt; /* 1 == PS1, 2 == PS2 */ - - -union node *parsecmd(int); -void fixredir(union node *, const char *, int); -int goodname(char *); -const char *getprompt(void *); diff --git a/sh/redir.c b/sh/redir.c deleted file mode 100644 index 5c4c28683d08f17fee7eeb6290d7640a0b187fd6..0000000000000000000000000000000000000000 --- a/sh/redir.c +++ /dev/null @@ -1,389 +0,0 @@ -/* $NetBSD: redir.c,v 1.29 2004/07/08 03:57:33 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: redir.c,v 1.29 2004/07/08 03:57:33 christos Exp $"); -#endif -#endif /* not lint */ - -#include <sys/types.h> -#include <sys/param.h> /* PIPE_BUF */ -#include <signal.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> -#include <unistd.h> -#include <stdlib.h> - -/* - * Code for dealing with input/output redirection. - */ - -#include "main.h" -#include "shell.h" -#include "nodes.h" -#include "jobs.h" -#include "options.h" -#include "expand.h" -#include "redir.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" - - -#define EMPTY -2 /* marks an unused slot in redirtab */ -#ifndef PIPE_BUF -# define PIPESIZE 4096 /* amount of buffering in a pipe */ -#else -# define PIPESIZE PIPE_BUF -#endif - -#define signal bsd_signal - -MKINIT -struct redirtab { - struct redirtab *next; - short renamed[10]; -}; - - -MKINIT struct redirtab *redirlist; - -/* - * We keep track of whether or not fd0 has been redirected. This is for - * background commands, where we want to redirect fd0 to /dev/null only - * if it hasn't already been redirected. -*/ -int fd0_redirected = 0; - -STATIC void openredirect(union node *, char[10], int); -STATIC int openhere(union node *); - - -/* - * Process a list of redirection commands. If the REDIR_PUSH flag is set, - * old file descriptors are stashed away so that the redirection can be - * undone by calling popredir. If the REDIR_BACKQ flag is set, then the - * standard output, and the standard error if it becomes a duplicate of - * stdout, is saved in memory. - */ - -void -redirect(union node *redir, int flags) -{ - union node *n; - struct redirtab *sv = NULL; - int i; - int fd; - int try; - char memory[10]; /* file descriptors to write to memory */ - - for (i = 10 ; --i >= 0 ; ) - memory[i] = 0; - memory[1] = flags & REDIR_BACKQ; - if (flags & REDIR_PUSH) { - /* We don't have to worry about REDIR_VFORK here, as - * flags & REDIR_PUSH is never true if REDIR_VFORK is set. - */ - sv = ckmalloc(sizeof (struct redirtab)); - for (i = 0 ; i < 10 ; i++) - sv->renamed[i] = EMPTY; - sv->next = redirlist; - redirlist = sv; - } - for (n = redir ; n ; n = n->nfile.next) { - fd = n->nfile.fd; - try = 0; - if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && - n->ndup.dupfd == fd) - continue; /* redirect from/to same file descriptor */ - - if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) { - INTOFF; -again: - if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { - switch (errno) { - case EBADF: - if (!try) { - openredirect(n, memory, flags); - try++; - goto again; - } - /* FALLTHROUGH*/ - default: - INTON; - error("%d: %s", fd, strerror(errno)); - /* NOTREACHED */ - } - } - if (!try) { - sv->renamed[fd] = i; - close(fd); - } - INTON; - } else { - close(fd); - } - if (fd == 0) - fd0_redirected++; - if (!try) - openredirect(n, memory, flags); - } - if (memory[1]) - out1 = &memout; - if (memory[2]) - out2 = &memout; -} - - -STATIC void -openredirect(union node *redir, char memory[10], int flags) -{ - int fd = redir->nfile.fd; - char *fname; - int f; - int oflags = O_WRONLY|O_CREAT|O_TRUNC, eflags; - - /* - * We suppress interrupts so that we won't leave open file - * descriptors around. This may not be such a good idea because - * an open of a device or a fifo can block indefinitely. - */ - INTOFF; - memory[fd] = 0; - switch (redir->nfile.type) { - case NFROM: - fname = redir->nfile.expfname; - if (flags & REDIR_VFORK) - eflags = O_NONBLOCK; - else - eflags = 0; - if ((f = open(fname, O_RDONLY|eflags)) < 0) - goto eopen; - if (eflags) - (void)fcntl(f, F_SETFL, fcntl(f, F_GETFL, 0) & ~eflags); - break; - case NFROMTO: - fname = redir->nfile.expfname; - if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) - goto ecreate; - break; - case NTO: - if (Cflag) - oflags |= O_EXCL; - /* FALLTHROUGH */ - case NCLOBBER: - fname = redir->nfile.expfname; - if ((f = open(fname, oflags, 0666)) < 0) - goto ecreate; - break; - case NAPPEND: - fname = redir->nfile.expfname; - if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) - goto ecreate; - break; - case NTOFD: - case NFROMFD: - if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ - if (memory[redir->ndup.dupfd]) - memory[fd] = 1; - else - copyfd(redir->ndup.dupfd, fd); - } - INTON; - return; - case NHERE: - case NXHERE: - f = openhere(redir); - break; - default: - abort(); - } - - if (f != fd) { - copyfd(f, fd); - close(f); - } - INTON; - return; -ecreate: - error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); -eopen: - error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); -} - - -/* - * Handle here documents. Normally we fork off a process to write the - * data to a pipe. If the document is short, we can stuff the data in - * the pipe without forking. - */ - -STATIC int -openhere(union node *redir) -{ - int pip[2]; - int len = 0; - - if (pipe(pip) < 0) - error("Pipe call failed"); - if (redir->type == NHERE) { - len = strlen(redir->nhere.doc->narg.text); - if (len <= PIPESIZE) { - xwrite(pip[1], redir->nhere.doc->narg.text, len); - goto out; - } - } - if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { - close(pip[0]); - signal(SIGINT, SIG_IGN); - signal(SIGQUIT, SIG_IGN); - signal(SIGHUP, SIG_IGN); -#ifdef SIGTSTP - signal(SIGTSTP, SIG_IGN); -#endif - signal(SIGPIPE, SIG_DFL); - if (redir->type == NHERE) - xwrite(pip[1], redir->nhere.doc->narg.text, len); - else - expandhere(redir->nhere.doc, pip[1]); - _exit(0); - } -out: - close(pip[1]); - return pip[0]; -} - - - -/* - * Undo the effects of the last redirection. - */ - -void -popredir(void) -{ - struct redirtab *rp = redirlist; - int i; - - for (i = 0 ; i < 10 ; i++) { - if (rp->renamed[i] != EMPTY) { - if (i == 0) - fd0_redirected--; - close(i); - if (rp->renamed[i] >= 0) { - copyfd(rp->renamed[i], i); - close(rp->renamed[i]); - } - } - } - INTOFF; - redirlist = rp->next; - ckfree(rp); - INTON; -} - -/* - * Undo all redirections. Called on error or interrupt. - */ - -#ifdef mkinit - -INCLUDE "redir.h" - -RESET { - while (redirlist) - popredir(); -} - -SHELLPROC { - clearredir(0); -} - -#endif - -/* Return true if fd 0 has already been redirected at least once. */ -int -fd0_redirected_p () { - return fd0_redirected != 0; -} - -/* - * Discard all saved file descriptors. - */ - -void -clearredir(vforked) - int vforked; -{ - struct redirtab *rp; - int i; - - for (rp = redirlist ; rp ; rp = rp->next) { - for (i = 0 ; i < 10 ; i++) { - if (rp->renamed[i] >= 0) { - close(rp->renamed[i]); - } - if (!vforked) - rp->renamed[i] = EMPTY; - } - } -} - - - -/* - * Copy a file descriptor to be >= to. Returns -1 - * if the source file descriptor is closed, EMPTY if there are no unused - * file descriptors left. - */ - -int -copyfd(int from, int to) -{ - int newfd; - - newfd = fcntl(from, F_DUPFD, to); - if (newfd < 0) { - if (errno == EMFILE) - return EMPTY; - else - error("%d: %s", from, strerror(errno)); - } - return newfd; -} diff --git a/sh/redir.h b/sh/redir.h deleted file mode 100644 index c9709e93bf26737a3a2be7f50fa0e2f590053ea8..0000000000000000000000000000000000000000 --- a/sh/redir.h +++ /dev/null @@ -1,48 +0,0 @@ -/* $NetBSD: redir.h,v 1.15 2003/08/07 09:05:37 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)redir.h 8.2 (Berkeley) 5/4/95 - */ - -/* flags passed to redirect */ -#define REDIR_PUSH 01 /* save previous values of file descriptors */ -#define REDIR_BACKQ 02 /* save the command output in memory */ -#define REDIR_VFORK 04 /* running under vfork(2), be careful */ - -union node; -void redirect(union node *, int); -void popredir(void); -int fd0_redirected_p(void); -void clearredir(int); -int copyfd(int, int); - diff --git a/sh/sh.1 b/sh/sh.1 deleted file mode 100644 index 3ef55b4fd240b08cfa5277f5c9dacd094aa808d1..0000000000000000000000000000000000000000 --- a/sh/sh.1 +++ /dev/null @@ -1,1928 +0,0 @@ -.\" $NetBSD: sh.1,v 1.78 2004/06/03 19:54:37 hubertf Exp $ -.\" Copyright (c) 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" This code is derived from software contributed to Berkeley by -.\" Kenneth Almquist. -.\" -.\" 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. -.\" 3. 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. -.\" -.\" @(#)sh.1 8.6 (Berkeley) 5/4/95 -.\" -.Dd April 17, 2004 -.Os -.Dt SH 1 -.Sh NAME -.Nm sh -.Nd command interpreter (shell) -.Sh SYNOPSIS -.Nm -.Bk -words -.Op Fl aCefnuvxIimqVEb -.Op Cm +aCefnuvxIimqVEb -.Ek -.Bk -words -.Op Fl o Ar option_name -.Op Cm +o Ar option_name -.Ek -.Bk -words -.Op Ar command_file Oo Ar argument ... Oc -.Ek -.Nm -.Fl c -.Bk -words -.Op Fl aCefnuvxIimqVEb -.Op Cm +aCefnuvxIimqVEb -.Ek -.Bk -words -.Op Fl o Ar option_name -.Op Cm +o Ar option_name -.Ek -.Bk -words -.Ar command_string -.Op Ar command_name Oo Ar argument ... Oc -.Ek -.Nm -.Fl s -.Bk -words -.Op Fl aCefnuvxIimqVEb -.Op Cm +aCefnuvxIimqVEb -.Ek -.Bk -words -.Op Fl o Ar option_name -.Op Cm +o Ar option_name -.Ek -.Bk -words -.Op Ar argument ... -.Ek -.Sh DESCRIPTION -.Nm -is the standard command interpreter for the system. -The current version of -.Nm -is in the process of being changed to conform with the -.Tn POSIX -1003.2 and 1003.2a specifications for the shell. -This version has many -features which make it appear similar in some respects to the Korn shell, -but it is not a Korn shell clone (see -.Xr ksh 1 ) . -Only features designated by -.Tn POSIX , -plus a few Berkeley extensions, are being incorporated into this shell. -.\" We expect -.\" .Tn POSIX -.\" conformance by the time 4.4 BSD is released. -This man page is not intended -to be a tutorial or a complete specification of the shell. -.Ss Overview -The shell is a command that reads lines from either a file or the -terminal, interprets them, and generally executes other commands. -It is the program that is running when a user logs into the system -(although a user can select a different shell with the -.Xr chsh 1 -command). -The shell implements a language that has flow control -constructs, a macro facility that provides a variety of features in -addition to data storage, along with built in history and line editing -capabilities. -It incorporates many features to aid interactive use and -has the advantage that the interpretative language is common to both -interactive and non-interactive use (shell scripts). -That is, commands -can be typed directly to the running shell or can be put into a file and -the file can be executed directly by the shell. -.Ss Invocation -If no args are present and if the standard input of the shell -is connected to a terminal (or if the -.Fl i -flag is set), -and the -.Fl c -option is not present, the shell is considered an interactive shell. -An interactive shell generally prompts before each command and handles -programming and command errors differently (as described below). -When first starting, -the shell inspects argument 0, and if it begins with a dash -.Sq - , -the shell is also considered -a login shell. -This is normally done automatically by the system -when the user first logs in. -A login shell first reads commands -from the files -.Pa /etc/profile -and -.Pa .profile -if they exist. -If the environment variable -.Ev ENV -is set on entry to a shell, or is set in the -.Pa .profile -of a login shell, the shell next reads -commands from the file named in -.Ev ENV . -Therefore, a user should place commands that are to be executed only at -login time in the -.Pa .profile -file, and commands that are executed for every shell inside the -.Ev ENV -file. -To set the -.Ev ENV -variable to some file, place the following line in your -.Pa .profile -of your home directory -.Pp -.Dl ENV=$HOME/.shinit; export ENV -.Pp -substituting for -.Dq .shinit -any filename you wish. -Since the -.Ev ENV -file is read for every invocation of the shell, including shell scripts -and non-interactive shells, the following paradigm is useful for -restricting commands in the -.Ev ENV -file to interactive invocations. -Place commands within the -.Dq case -and -.Dq esac -below (these commands are described later): -.Pp -.Bl -item -compact -offset indent -.It -.Li case $- in *i*) -.Bl -item -compact -offset indent -.It -.Li # commands for interactive use only -.It -.Li ... -.El -.It -.Li esac -.El -.Pp -If command line arguments besides the options have been specified, then -the shell treats the first argument as the name of a file from which to -read commands (a shell script), and the remaining arguments are set as the -positional parameters of the shell ($1, $2, etc). -Otherwise, the shell -reads commands from its standard input. -.Ss Argument List Processing -All of the single letter options have a corresponding name that can be -used as an argument to the -.Fl o -option. -The set -.Fl o -name is provided next to the single letter option in -the description below. -Specifying a dash -.Dq - -turns the option on, while using a plus -.Dq + -disables the option. -The following options can be set from the command line or -with the -.Ic set -builtin (described later). -.Bl -tag -width aaaallexportfoo -offset indent -.It Fl a Em allexport -Export all variables assigned to. -.It Fl c -Read commands from the -.Ar command_string -operand instead of from the standard input. -Special parameter 0 will be set from the -.Ar command_name -operand and the positional parameters ($1, $2, etc.) -set from the remaining argument operands. -.It Fl C Em noclobber -Don't overwrite existing files with -.Dq \*[Gt] . -.It Fl e Em errexit -If not interactive, exit immediately if any untested command fails. -The exit status of a command is considered to be -explicitly tested if the command is used to control an -.Ic if , -.Ic elif , -.Ic while , -or -.Ic until ; -or if the command is the left hand operand of an -.Dq \*[Am]\*[Am] -or -.Dq || -operator. -.It Fl f Em noglob -Disable pathname expansion. -.It Fl n Em noexec -If not interactive, read commands but do not execute them. -This is useful for checking the syntax of shell scripts. -.It Fl u Em nounset -Write a message to standard error when attempting to expand a variable -that is not set, and if the shell is not interactive, exit immediately. -.It Fl v Em verbose -The shell writes its input to standard error as it is read. -Useful for debugging. -.It Fl x Em xtrace -Write each command to standard error (preceded by a -.Sq +\ ) -before it is executed. -Useful for debugging. -.It Fl q Em quietprofile -If the -.Fl v -or -.Fl x -options have been set, do not apply them when reading -initialization files, these being -.Pa /etc/profile , -.Pa .profile , -and the file specified by the -.Ev ENV -environment variable. -.It Fl I Em ignoreeof -Ignore EOF's from input when interactive. -.It Fl i Em interactive -Force the shell to behave interactively. -.It Fl m Em monitor -Turn on job control (set automatically when interactive). -.It Fl s Em stdin -Read commands from standard input (set automatically if no file arguments -are present). -This option has no effect when set after the shell has -already started running (i.e. with -.Ic set ) . -.It Fl V Em vi -Enable the built-in -.Xr vi 1 -command line editor (disables -.Fl E -if it has been set). -(See the -.Sx Command Line Editing -section below.) -.It Fl E Em emacs -Enable the built-in emacs style -command line editor (disables -.Fl V -if it has been set). -(See the -.Sx Command Line Editing -section below.) -.It Fl b Em notify -Enable asynchronous notification of background job completion. -(UNIMPLEMENTED for 4.4alpha) -.It "\ \ " Em cdprint -Make an interactive shell always print the new directory name when -changed by the -.Ic cd -command. -.El -.Ss Lexical Structure -The shell reads input in terms of lines from a file and breaks it up into -words at whitespace (blanks and tabs), and at certain sequences of -characters that are special to the shell called -.Dq operators . -There are two types of operators: control operators and redirection -operators (their meaning is discussed later). -Following is a list of operators: -.Bl -ohang -offset indent -.It "Control operators:" -.Dl \*[Am] \*[Am]\*[Am] \&( \&) \&; ;; | || \*[Lt]newline\*[Gt] -.It "Redirection operators:" -.Dl \*[Lt] \*[Gt] \*[Gt]| \*[Lt]\*[Lt] \*[Gt]\*[Gt] \*[Lt]\*[Am] \*[Gt]\*[Am] \*[Lt]\*[Lt]- \*[Lt]\*[Gt] -.El -.Ss Quoting -Quoting is used to remove the special meaning of certain characters or -words to the shell, such as operators, whitespace, or keywords. -There are three types of quoting: matched single quotes, -matched double quotes, and backslash. -.Ss Backslash -A backslash preserves the literal meaning of the following -character, with the exception of -.Aq newline . -A backslash preceding a -.Aq newline -is treated as a line continuation. -.Ss Single Quotes -Enclosing characters in single quotes preserves the literal meaning of all -the characters (except single quotes, making it impossible to put -single-quotes in a single-quoted string). -.Ss Double Quotes -Enclosing characters within double quotes preserves the literal -meaning of all characters except dollarsign -.Pq $ , -backquote -.Pq ` , -and backslash -.Pq \e . -The backslash inside double quotes is historically weird, and serves to -quote only the following characters: -.Dl $ ` \*q \e \*[Lt]newline\*[Gt] . -Otherwise it remains literal. -.Ss Reserved Words -Reserved words are words that have special meaning to the -shell and are recognized at the beginning of a line and -after a control operator. -The following are reserved words: -.Bl -column while while while while while -offset indent -.It ! Ta elif Ta fi Ta while Ta case -.It else Ta for Ta then Ta { Ta } -.It do Ta done Ta until Ta if Ta esac -.El -.Pp -Their meaning is discussed later. -.Ss Aliases -An alias is a name and corresponding value set using the -.Ic alias -builtin command. -Whenever a reserved word may occur (see above), -and after checking for reserved words, the shell -checks the word to see if it matches an alias. -If it does, it replaces it in the input stream with its value. -For example, if there is an alias called -.Dq lf -with the value -.Dq "ls -F" , -then the input: -.Pp -.Dl lf foobar Aq return -.Pp -would become -.Pp -.Dl ls -F foobar Aq return -.Pp -Aliases provide a convenient way for naive users to create shorthands for -commands without having to learn how to create functions with arguments. -They can also be used to create lexically obscure code. -This use is discouraged. -.Ss Commands -The shell interprets the words it reads according to a language, the -specification of which is outside the scope of this man page (refer to the -BNF in the -.Tn POSIX -1003.2 document). -Essentially though, a line is read and if the first -word of the line (or after a control operator) is not a reserved word, -then the shell has recognized a simple command. -Otherwise, a complex -command or some other special construct may have been recognized. -.Ss Simple Commands -If a simple command has been recognized, the shell performs -the following actions: -.Bl -enum -offset indent -.It -Leading words of the form -.Dq name=value -are stripped off and assigned to the environment of the simple command. -Redirection operators and their arguments (as described below) are -stripped off and saved for processing. -.It -The remaining words are expanded as described in -the section called -.Dq Expansions , -and the first remaining word is considered the command name and the -command is located. -The remaining words are considered the arguments of the command. -If no command name resulted, then the -.Dq name=value -variable assignments recognized in item 1 affect the current shell. -.It -Redirections are performed as described in the next section. -.El -.Ss Redirections -Redirections are used to change where a command reads its input or sends -its output. -In general, redirections open, close, or duplicate an -existing reference to a file. -The overall format used for redirection is: -.Pp -.Dl [n] Va redir-op Ar file -.Pp -where -.Va redir-op -is one of the redirection operators mentioned previously. -Following is a list of the possible redirections. -The -.Bq n -is an optional number, as in -.Sq 3 -(not -.Sq Bq 3 ) , -that refers to a file descriptor. -.Bl -tag -width aaabsfiles -offset indent -.It [n] Ns \*[Gt] file -Redirect standard output (or n) to file. -.It [n] Ns \*[Gt]| file -Same, but override the -.Fl C -option. -.It [n] Ns \*[Gt]\*[Gt] file -Append standard output (or n) to file. -.It [n] Ns \*[Lt] file -Redirect standard input (or n) from file. -.It [n1] Ns \*[Lt]\*[Am] Ns n2 -Duplicate standard input (or n1) from file descriptor n2. -.It [n] Ns \*[Lt]\*[Am]- -Close standard input (or n). -.It [n1] Ns \*[Gt]\*[Am] Ns n2 -Duplicate standard output (or n1) to n2. -.It [n] Ns \*[Gt]\*[Am]- -Close standard output (or n). -.It [n] Ns \*[Lt]\*[Gt] file -Open file for reading and writing on standard input (or n). -.El -.Pp -The following redirection is often called a -.Dq here-document . -.Bl -item -offset indent -.It -.Li [n]\*[Lt]\*[Lt] delimiter -.Dl here-doc-text ... -.Li delimiter -.El -.Pp -All the text on successive lines up to the delimiter is saved away and -made available to the command on standard input, or file descriptor n if -it is specified. -If the delimiter as specified on the initial line is -quoted, then the here-doc-text is treated literally, otherwise the text is -subjected to parameter expansion, command substitution, and arithmetic -expansion (as described in the section on -.Dq Expansions ) . -If the operator is -.Dq \*[Lt]\*[Lt]- -instead of -.Dq \*[Lt]\*[Lt] , -then leading tabs in the here-doc-text are stripped. -.Ss Search and Execution -There are three types of commands: shell functions, builtin commands, and -normal programs -- and the command is searched for (by name) in that order. -They each are executed in a different way. -.Pp -When a shell function is executed, all of the shell positional parameters -(except $0, which remains unchanged) are set to the arguments of the shell -function. -The variables which are explicitly placed in the environment of -the command (by placing assignments to them before the function name) are -made local to the function and are set to the values given. -Then the command given in the function definition is executed. -The positional parameters are restored to their original values -when the command completes. -This all occurs within the current shell. -.Pp -Shell builtins are executed internally to the shell, without spawning a -new process. -.Pp -Otherwise, if the command name doesn't match a function or builtin, the -command is searched for as a normal program in the file system (as -described in the next section). -When a normal program is executed, the shell runs the program, -passing the arguments and the environment to the program. -If the program is not a normal executable file (i.e., if it does -not begin with the "magic number" whose -.Tn ASCII -representation is "#!", so -.Xr execve 2 -returns -.Er ENOEXEC -then) the shell will interpret the program in a subshell. -The child shell will reinitialize itself in this case, -so that the effect will be as if a -new shell had been invoked to handle the ad-hoc shell script, except that -the location of hashed commands located in the parent shell will be -remembered by the child. -.Pp -Note that previous versions of this document and the source code itself -misleadingly and sporadically refer to a shell script without a magic -number as a "shell procedure". -.Ss Path Search -When locating a command, the shell first looks to see if it has a shell -function by that name. -Then it looks for a builtin command by that name. -If a builtin command is not found, one of two things happen: -.Bl -enum -.It -Command names containing a slash are simply executed without performing -any searches. -.It -The shell searches each entry in -.Ev PATH -in turn for the command. -The value of the -.Ev PATH -variable should be a series of entries separated by colons. -Each entry consists of a directory name. -The current directory may be indicated -implicitly by an empty directory name, or explicitly by a single period. -.El -.Ss Command Exit Status -Each command has an exit status that can influence the behavior -of other shell commands. -The paradigm is that a command exits -with zero for normal or success, and non-zero for failure, -error, or a false indication. -The man page for each command -should indicate the various exit codes and what they mean. -Additionally, the builtin commands return exit codes, as does -an executed shell function. -.Pp -If a command consists entirely of variable assignments then the -exit status of the command is that of the last command substitution -if any, otherwise 0. -.Ss Complex Commands -Complex commands are combinations of simple commands with control -operators or reserved words, together creating a larger complex command. -More generally, a command is one of the following: -.Bl -bullet -.It -simple command -.It -pipeline -.It -list or compound-list -.It -compound command -.It -function definition -.El -.Pp -Unless otherwise stated, the exit status of a command is that of the last -simple command executed by the command. -.Ss Pipelines -A pipeline is a sequence of one or more commands separated -by the control operator |. -The standard output of all but -the last command is connected to the standard input -of the next command. -The standard output of the last -command is inherited from the shell, as usual. -.Pp -The format for a pipeline is: -.Pp -.Dl [!] command1 [ | command2 ...] -.Pp -The standard output of command1 is connected to the standard input of -command2. -The standard input, standard output, or both of a command is -considered to be assigned by the pipeline before any redirection specified -by redirection operators that are part of the command. -.Pp -If the pipeline is not in the background (discussed later), the shell -waits for all commands to complete. -.Pp -If the reserved word ! does not precede the pipeline, the exit status is -the exit status of the last command specified in the pipeline. -Otherwise, the exit status is the logical NOT of the exit status of the -last command. -That is, if the last command returns zero, the exit status -is 1; if the last command returns greater than zero, the exit status is -zero. -.Pp -Because pipeline assignment of standard input or standard output or both -takes place before redirection, it can be modified by redirection. -For example: -.Pp -.Dl $ command1 2\*[Gt]\*[Am]1 | command2 -.Pp -sends both the standard output and standard error of command1 -to the standard input of command2. -.Pp -A ; or -.Aq newline -terminator causes the preceding AND-OR-list (described -next) to be executed sequentially; a \*[Am] causes asynchronous execution of -the preceding AND-OR-list. -.Pp -Note that unlike some other shells, each process in the pipeline is a -child of the invoking shell (unless it is a shell builtin, in which case -it executes in the current shell -- but any effect it has on the -environment is wiped). -.Ss Background Commands -- \*[Am] -If a command is terminated by the control operator ampersand (\*[Am]), the -shell executes the command asynchronously -- that is, the shell does not -wait for the command to finish before executing the next command. -.Pp -The format for running a command in background is: -.Pp -.Dl command1 \*[Am] [command2 \*[Am] ...] -.Pp -If the shell is not interactive, the standard input of an asynchronous -command is set to -.Pa /dev/null . -.Ss Lists -- Generally Speaking -A list is a sequence of zero or more commands separated by newlines, -semicolons, or ampersands, and optionally terminated by one of these three -characters. -The commands in a list are executed in the order they are written. -If command is followed by an ampersand, the shell starts the -command and immediately proceed onto the next command; otherwise it waits -for the command to terminate before proceeding to the next one. -.Ss Short-Circuit List Operators -.Dq \*[Am]\*[Am] -and -.Dq || -are AND-OR list operators. -.Dq \*[Am]\*[Am] -executes the first command, and then executes the second command if and only -if the exit status of the first command is zero. -.Dq || -is similar, but executes the second command if and only if the exit status -of the first command is nonzero. -.Dq \*[Am]\*[Am] -and -.Dq || -both have the same priority. -Note that these operators are left-associative, so -.Dq true || echo bar && echo baz -writes -.Dq baz -and nothing else. -This is not the way it works in C. -.Ss Flow-Control Constructs -- if, while, for, case -The syntax of the if command is -.Bd -literal -offset indent -if list -then list -[ elif list -then list ] ... -[ else list ] -fi -.Ed -.Pp -The syntax of the while command is -.Bd -literal -offset indent -while list -do list -done -.Ed -.Pp -The two lists are executed repeatedly while the exit status of the -first list is zero. -The until command is similar, but has the word -until in place of while, which causes it to -repeat until the exit status of the first list is zero. -.Pp -The syntax of the for command is -.Bd -literal -offset indent -for variable in word ... -do list -done -.Ed -.Pp -The words are expanded, and then the list is executed repeatedly with the -variable set to each word in turn. -do and done may be replaced with -.Dq { -and -.Dq } . -.Pp -The syntax of the break and continue command is -.Bd -literal -offset indent -break [ num ] -continue [ num ] -.Ed -.Pp -Break terminates the num innermost for or while loops. -Continue continues with the next iteration of the innermost loop. -These are implemented as builtin commands. -.Pp -The syntax of the case command is -.Bd -literal -offset indent -case word in -pattern) list ;; -\&... -esac -.Ed -.Pp -The pattern can actually be one or more patterns (see -.Sx Shell Patterns -described later), separated by -.Dq \*(Ba -characters. -.Ss Grouping Commands Together -Commands may be grouped by writing either -.Pp -.Dl (list) -.Pp -or -.Pp -.Dl { list; } -.Pp -The first of these executes the commands in a subshell. -Builtin commands grouped into a (list) will not affect the current shell. -The second form does not fork another shell so is slightly more efficient. -Grouping commands together this way allows you to redirect -their output as though they were one program: -.Pp -.Bd -literal -offset indent -{ echo -n \*q hello \*q ; echo \*q world" ; } \*[Gt] greeting -.Ed -.Pp -Note that -.Dq } -must follow a control operator (here, -.Dq \&; ) -so that it is recognized as a reserved word and not as another command argument. -.Ss Functions -The syntax of a function definition is -.Pp -.Dl name ( ) command -.Pp -A function definition is an executable statement; when executed it -installs a function named name and returns an exit status of zero. -The command is normally a list enclosed between -.Dq { -and -.Dq } . -.Pp -Variables may be declared to be local to a function by using a local -command. -This should appear as the first statement of a function, and the syntax is -.Pp -.Dl local [ variable | - ] ... -.Pp -Local is implemented as a builtin command. -.Pp -When a variable is made local, it inherits the initial value and exported -and readonly flags from the variable with the same name in the surrounding -scope, if there is one. -Otherwise, the variable is initially unset. -The shell uses dynamic scoping, so that if you make the variable x local to -function f, which then calls function g, references to the variable x made -inside g will refer to the variable x declared inside f, not to the global -variable named x. -.Pp -The only special parameter that can be made local is -.Dq - . -Making -.Dq - -local any shell options that are changed via the set command inside the -function to be restored to their original values when the function -returns. -.Pp -The syntax of the return command is -.Pp -.Dl return [ exitstatus ] -.Pp -It terminates the currently executing function. -Return is implemented as a builtin command. -.Ss Variables and Parameters -The shell maintains a set of parameters. -A parameter denoted by a name is called a variable. -When starting up, the shell turns all the environment -variables into shell variables. -New variables can be set using the form -.Pp -.Dl name=value -.Pp -Variables set by the user must have a name consisting solely of -alphabetics, numerics, and underscores - the first of which must not be -numeric. -A parameter can also be denoted by a number or a special -character as explained below. -.Ss Positional Parameters -A positional parameter is a parameter denoted by a number (n \*[Gt] 0). -The shell sets these initially to the values of its command line arguments -that follow the name of the shell script. -The -.Ic set -builtin can also be used to set or reset them. -.Ss Special Parameters -A special parameter is a parameter denoted by one of the following special -characters. -The value of the parameter is listed next to its character. -.Bl -tag -width thinhyphena -.It * -Expands to the positional parameters, starting from one. -When the -expansion occurs within a double-quoted string it expands to a single -field with the value of each parameter separated by the first character of -the -.Ev IFS -variable, or by a -.Aq space -if -.Ev IFS -is unset. -.It @ -Expands to the positional parameters, starting from one. -When the expansion occurs within double-quotes, each positional -parameter expands as a separate argument. -If there are no positional parameters, the -expansion of @ generates zero arguments, even when @ is -double-quoted. -What this basically means, for example, is -if $1 is -.Dq abc -and $2 is -.Dq def ghi , -then -.Qq $@ -expands to -the two arguments: -.Pp -.Sm off -.Dl \*q abc \*q \ \*q def\ ghi \*q -.Sm on -.It # -Expands to the number of positional parameters. -.It \&? -Expands to the exit status of the most recent pipeline. -.It - (Hyphen.) -Expands to the current option flags (the single-letter -option names concatenated into a string) as specified on -invocation, by the set builtin command, or implicitly -by the shell. -.It $ -Expands to the process ID of the invoked shell. -A subshell retains the same value of $ as its parent. -.It \&! -Expands to the process ID of the most recent background -command executed from the current shell. -For a pipeline, the process ID is that of the last command in the pipeline. -.It 0 (Zero.) -Expands to the name of the shell or shell script. -.El -.Ss Word Expansions -This clause describes the various expansions that are performed on words. -Not all expansions are performed on every word, as explained later. -.Pp -Tilde expansions, parameter expansions, command substitutions, arithmetic -expansions, and quote removals that occur within a single word expand to a -single field. -It is only field splitting or pathname expansion that can -create multiple fields from a single word. -The single exception to this -rule is the expansion of the special parameter @ within double-quotes, as -was described above. -.Pp -The order of word expansion is: -.Bl -enum -.It -Tilde Expansion, Parameter Expansion, Command Substitution, -Arithmetic Expansion (these all occur at the same time). -.It -Field Splitting is performed on fields -generated by step (1) unless the -.Ev IFS -variable is null. -.It -Pathname Expansion (unless set -.Fl f -is in effect). -.It -Quote Removal. -.El -.Pp -The $ character is used to introduce parameter expansion, command -substitution, or arithmetic evaluation. -.Ss Tilde Expansion (substituting a user's home directory) -A word beginning with an unquoted tilde character (~) is -subjected to tilde expansion. -All the characters up to -a slash (/) or the end of the word are treated as a username -and are replaced with the user's home directory. -If the username is missing (as in -.Pa ~/foobar ) , -the tilde is replaced with the value of the -.Va HOME -variable (the current user's home directory). -.Ss Parameter Expansion -The format for parameter expansion is as follows: -.Pp -.Dl ${expression} -.Pp -where expression consists of all characters until the matching -.Dq } . -Any -.Dq } -escaped by a backslash or within a quoted string, and characters in -embedded arithmetic expansions, command substitutions, and variable -expansions, are not examined in determining the matching -.Dq } . -.Pp -The simplest form for parameter expansion is: -.Pp -.Dl ${parameter} -.Pp -The value, if any, of parameter is substituted. -.Pp -The parameter name or symbol can be enclosed in braces, which are -optional except for positional parameters with more than one digit or -when parameter is followed by a character that could be interpreted as -part of the name. -If a parameter expansion occurs inside double-quotes: -.Bl -enum -.It -Pathname expansion is not performed on the results of the expansion. -.It -Field splitting is not performed on the results of the -expansion, with the exception of @. -.El -.Pp -In addition, a parameter expansion can be modified by using one of the -following formats. -.Bl -tag -width aaparameterwordaaaaa -.It ${parameter:-word} -Use Default Values. -If parameter is unset or null, the expansion of word -is substituted; otherwise, the value of parameter is substituted. -.It ${parameter:=word} -Assign Default Values. -If parameter is unset or null, the expansion of -word is assigned to parameter. -In all cases, the final value of parameter is substituted. -Only variables, not positional parameters or special -parameters, can be assigned in this way. -.It ${parameter:?[word]} -Indicate Error if Null or Unset. -If parameter is unset or null, the -expansion of word (or a message indicating it is unset if word is omitted) -is written to standard error and the shell exits with a nonzero exit status. -Otherwise, the value of parameter is substituted. -An interactive shell need not exit. -.It ${parameter:+word} -Use Alternative Value. -If parameter is unset or null, null is -substituted; otherwise, the expansion of word is substituted. -.El -.Pp -In the parameter expansions shown previously, use of the colon in the -format results in a test for a parameter that is unset or null; omission -of the colon results in a test for a parameter that is only unset. -.Bl -tag -width aaparameterwordaaaaa -.It ${#parameter} -String Length. -The length in characters of the value of parameter. -.El -.Pp -The following four varieties of parameter expansion provide for substring -processing. -In each case, pattern matching notation (see -.Sx Shell Patterns ) , -rather than regular expression notation, is used to evaluate the patterns. -If parameter is * or @, the result of the expansion is unspecified. -Enclosing the full parameter expansion string in double-quotes does not -cause the following four varieties of pattern characters to be quoted, -whereas quoting characters within the braces has this effect. -.Bl -tag -width aaparameterwordaaaaa -.It ${parameter%word} -Remove Smallest Suffix Pattern. -The word is expanded to produce a pattern. -The parameter expansion then results in parameter, with the -smallest portion of the suffix matched by the pattern deleted. -.It ${parameter%%word} -Remove Largest Suffix Pattern. -The word is expanded to produce a pattern. -The parameter expansion then results in parameter, with the largest -portion of the suffix matched by the pattern deleted. -.It ${parameter#word} -Remove Smallest Prefix Pattern. -The word is expanded to produce a pattern. -The parameter expansion then results in parameter, with the -smallest portion of the prefix matched by the pattern deleted. -.It ${parameter##word} -Remove Largest Prefix Pattern. -The word is expanded to produce a pattern. -The parameter expansion then results in parameter, with the largest -portion of the prefix matched by the pattern deleted. -.El -.Ss Command Substitution -Command substitution allows the output of a command to be substituted in -place of the command name itself. -Command substitution occurs when the command is enclosed as follows: -.Pp -.Dl $(command) -.Pp -or -.Po -.Dq backquoted -version -.Pc : -.Pp -.Dl `command` -.Pp -The shell expands the command substitution by executing command in a -subshell environment and replacing the command substitution with the -standard output of the command, removing sequences of one or more -.Ao newline Ac Ns s -at the end of the substitution. -(Embedded -.Ao newline Ac Ns s -before -the end of the output are not removed; however, during field splitting, -they may be translated into -.Ao space Ac Ns s , -depending on the value of -.Ev IFS -and quoting that is in effect.) -.Ss Arithmetic Expansion -Arithmetic expansion provides a mechanism for evaluating an arithmetic -expression and substituting its value. -The format for arithmetic expansion is as follows: -.Pp -.Dl $((expression)) -.Pp -The expression is treated as if it were in double-quotes, except -that a double-quote inside the expression is not treated specially. -The shell expands all tokens in the expression for parameter expansion, -command substitution, and quote removal. -.Pp -Next, the shell treats this as an arithmetic expression and -substitutes the value of the expression. -.Ss White Space Splitting (Field Splitting) -After parameter expansion, command substitution, and -arithmetic expansion the shell scans the results of -expansions and substitutions that did not occur in double-quotes for -field splitting and multiple fields can result. -.Pp -The shell treats each character of the -.Ev IFS -as a delimiter and use the delimiters to split the results of parameter -expansion and command substitution into fields. -.Ss Pathname Expansion (File Name Generation) -Unless the -.Fl f -flag is set, file name generation is performed after word splitting is -complete. -Each word is viewed as a series of patterns, separated by slashes. -The process of expansion replaces the word with the names of all -existing files whose names can be formed by replacing each pattern with a -string that matches the specified pattern. -There are two restrictions on -this: first, a pattern cannot match a string containing a slash, and -second, a pattern cannot match a string starting with a period unless the -first character of the pattern is a period. -The next section describes the -patterns used for both Pathname Expansion and the -.Ic case -command. -.Ss Shell Patterns -A pattern consists of normal characters, which match themselves, -and meta-characters. -The meta-characters are -.Dq \&! , -.Dq * , -.Dq \&? , -and -.Dq \&[ . -These characters lose their special meanings if they are quoted. -When command or variable substitution is performed -and the dollar sign or back quotes are not double quoted, -the value of the variable or the output of -the command is scanned for these characters and they are turned into -meta-characters. -.Pp -An asterisk -.Pq Dq * -matches any string of characters. -A question mark matches any single character. -A left bracket -.Pq Dq \&[ -introduces a character class. -The end of the character class is indicated by a -.Pq Dq \&] ; -if the -.Dq \&] -is missing then the -.Dq \&[ -matches a -.Dq \&[ -rather than introducing a character class. -A character class matches any of the characters between the square brackets. -A range of characters may be specified using a minus sign. -The character class may be complemented -by making an exclamation point the first character of the character class. -.Pp -To include a -.Dq \&] -in a character class, make it the first character listed (after the -.Dq \&! , -if any). -To include a minus sign, make it the first or last character listed. -.Ss Builtins -This section lists the builtin commands which are builtin because they -need to perform some operation that can't be performed by a separate -process. -In addition to these, there are several other commands that may -be builtin for efficiency (e.g. -.Xr printf 1 , -.Xr echo 1 , -.Xr test 1 , -etc). -.Bl -tag -width 5n -.It : -A null command that returns a 0 (true) exit value. -.It \&. file -The commands in the specified file are read and executed by the shell. -.It alias Op Ar name Ns Op Ar "=string ..." -If -.Ar name=string -is specified, the shell defines the alias -.Ar name -with value -.Ar string . -If just -.Ar name -is specified, the value of the alias -.Ar name -is printed. -With no arguments, the -.Ic alias -builtin prints the -names and values of all defined aliases (see -.Ic unalias ) . -.It bg [ Ar job ] ... -Continue the specified jobs (or the current job if no -jobs are given) in the background. -.It Xo command -.Op Fl p -.Op Fl v -.Op Fl V -.Ar command -.Op Ar arg ... -.Xc -Execute the specified command but ignore shell functions when searching -for it. -(This is useful when you -have a shell function with the same name as a builtin command.) -.Bl -tag -width 5n -.It Fl p -search for command using a -.Ev PATH -that guarantees to find all the standard utilities. -.It Fl V -Do not execute the command but -search for the command and print the resolution of the -command search. -This is the same as the type builtin. -.It Fl v -Do not execute the command but -search for the command and print the absolute pathname -of utilities, the name for builtins or the expansion of aliases. -.El -.It cd Op Ar directory Op Ar replace -Switch to the specified directory (default -.Ev $HOME ) . -If -.Ar replace -is specified, then the new directory name is generated by replacing -the first occurrence of -.Ar directory -in the current directory name with -.Ar replace . -Otherwise if an entry for -.Ev CDPATH -appears in the environment of the -.Ic cd -command or the shell variable -.Ev CDPATH -is set and the directory name does not begin with a slash, then the -directories listed in -.Ev CDPATH -will be searched for the specified directory. -The format of -.Ev CDPATH -is the same as that of -.Ev PATH . -In an interactive shell, the -.Ic cd -command will print out the name of the -directory that it actually switched to if this is different from the name -that the user gave. -These may be different either because the -.Ev CDPATH -mechanism was used or because a symbolic link was crossed. -.It eval Ar string ... -Concatenate all the arguments with spaces. -Then re-parse and execute the command. -.It exec Op Ar command arg ... -Unless command is omitted, the shell process is replaced with the -specified program (which must be a real program, not a shell builtin or -function). -Any redirections on the -.Ic exec -command are marked as permanent, so that they are not undone when the -.Ic exec -command finishes. -.It exit Op Ar exitstatus -Terminate the shell process. -If -.Ar exitstatus -is given it is used as the exit status of the shell; otherwise the -exit status of the preceding command is used. -.It export Ar name ... -.It export Fl p -The specified names are exported so that they will appear in the -environment of subsequent commands. -The only way to un-export a variable is to unset it. -The shell allows the value of a variable to be set at the -same time it is exported by writing -.Pp -.Dl export name=value -.Pp -With no arguments the export command lists the names of all exported variables. -With the -.Fl p -option specified the output will be formatted suitably for non-interactive use. -.It Xo fc Op Fl e Ar editor -.Op Ar first Op Ar last -.Xc -.It Xo fc Fl l -.Op Fl nr -.Op Ar first Op Ar last -.Xc -.It Xo fc Fl s Op Ar old=new -.Op Ar first -.Xc -The -.Ic fc -builtin lists, or edits and re-executes, commands previously entered -to an interactive shell. -.Bl -tag -width 5n -.It Fl e No editor -Use the editor named by editor to edit the commands. -The editor string is a command name, subject to search via the -.Ev PATH -variable. -The value in the -.Ev FCEDIT -variable is used as a default when -.Fl e -is not specified. -If -.Ev FCEDIT -is null or unset, the value of the -.Ev EDITOR -variable is used. -If -.Ev EDITOR -is null or unset, -.Xr ed 1 -is used as the editor. -.It Fl l No (ell) -List the commands rather than invoking an editor on them. -The commands are written in the sequence indicated by -the first and last operands, as affected by -.Fl r , -with each command preceded by the command number. -.It Fl n -Suppress command numbers when listing with -l. -.It Fl r -Reverse the order of the commands listed (with -.Fl l ) -or edited (with neither -.Fl l -nor -.Fl s ) . -.It Fl s -Re-execute the command without invoking an editor. -.It first -.It last -Select the commands to list or edit. -The number of previous commands that -can be accessed are determined by the value of the -.Ev HISTSIZE -variable. -The value of first or last or both are one of the following: -.Bl -tag -width 5n -.It [+]number -A positive number representing a command number; command numbers can be -displayed with the -.Fl l -option. -.It Fl number -A negative decimal number representing the command that was executed -number of commands previously. -For example, \-1 is the immediately previous command. -.El -.It string -A string indicating the most recently entered command that begins with -that string. -If the old=new operand is not also specified with -.Fl s , -the string form of the first operand cannot contain an embedded equal sign. -.El -.Pp -The following environment variables affect the execution of fc: -.Bl -tag -width HISTSIZE -.It Ev FCEDIT -Name of the editor to use. -.It Ev HISTSIZE -The number of previous commands that are accessible. -.El -.It fg Op Ar job -Move the specified job or the current job to the foreground. -.It getopts Ar optstring var -The -.Tn POSIX -.Ic getopts -command, not to be confused with the -.Em Bell Labs --derived -.Xr getopt 1 . -.Pp -The first argument should be a series of letters, each of which may be -optionally followed by a colon to indicate that the option requires an -argument. -The variable specified is set to the parsed option. -.Pp -The -.Ic getopts -command deprecates the older -.Xr getopt 1 -utility due to its handling of arguments containing whitespace. -.Pp -The -.Ic getopts -builtin may be used to obtain options and their arguments -from a list of parameters. -When invoked, -.Ic getopts -places the value of the next option from the option string in the list in -the shell variable specified by -.Va var -and its index in the shell variable -.Ev OPTIND . -When the shell is invoked, -.Ev OPTIND -is initialized to 1. -For each option that requires an argument, the -.Ic getopts -builtin will place it in the shell variable -.Ev OPTARG . -If an option is not allowed for in the -.Va optstring , -then -.Ev OPTARG -will be unset. -.Pp -.Va optstring -is a string of recognized option letters (see -.Xr getopt 3 ) . -If a letter is followed by a colon, the option is expected to have an -argument which may or may not be separated from it by white space. -If an option character is not found where expected, -.Ic getopts -will set the variable -.Va var -to a -.Dq \&? ; -.Ic getopts -will then unset -.Ev OPTARG -and write output to standard error. -By specifying a colon as the first character of -.Va optstring -all errors will be ignored. -.Pp -A nonzero value is returned when the last option is reached. -If there are no remaining arguments, -.Ic getopts -will set -.Va var -to the special option, -.Dq -- , -otherwise, it will set -.Va var -to -.Dq \&? . -.Pp -The following code fragment shows how one might process the arguments -for a command that can take the options -.Op a -and -.Op b , -and the option -.Op c , -which requires an argument. -.Pp -.Bd -literal -offset indent -while getopts abc: f -do - case $f in - a | b) flag=$f;; - c) carg=$OPTARG;; - \\?) echo $USAGE; exit 1;; - esac -done -shift `expr $OPTIND - 1` -.Ed -.Pp -This code will accept any of the following as equivalent: -.Pp -.Bd -literal -offset indent -cmd \-acarg file file -cmd \-a \-c arg file file -cmd \-carg -a file file -cmd \-a \-carg \-\- file file -.Ed -.It hash Fl rv Ar command ... -The shell maintains a hash table which remembers the -locations of commands. -With no arguments whatsoever, -the -.Ic hash -command prints out the contents of this table. -Entries which have not been looked at since the last -.Ic cd -command are marked with an asterisk; it is possible for these entries -to be invalid. -.Pp -With arguments, the -.Ic hash -command removes the specified commands from the hash table (unless -they are functions) and then locates them. -With the -.Fl v -option, hash prints the locations of the commands as it finds them. -The -.Fl r -option causes the hash command to delete all the entries in the hash table -except for functions. -.It inputrc Ar file -Read the -.Va file -to set keybindings as defined by -.Xr editrc 5 . -.It jobid Op Ar job -Print the process id's of the processes in the job. -If the -.Ar job -argument is omitted, the current job is used. -.It jobs -This command lists out all the background processes -which are children of the current shell process. -.It pwd Op Fl LP -Print the current directory. -If -.Fl L -is specified the cached value (initially set from -.Ev PWD ) -is checked to see if it refers to the current directory, if it does -the value is printed. -Otherwise the current directory name is found using -.Xr getcwd(3) . -The environment variable -.Ev PWD -is set to printed value. -.Pp -The default is -.Ic pwd -.Fl L , -but note that the builtin -.Ic cd -command doesn't currently support -.Fl L -or -.Fl P -and will cache (almost) the absolute path. -If -.Ic cd -is changed, -.Ic pwd -may be changed to default to -.Ic pwd -.Fl P . -.Pp -If the current directory is renamed and replaced by a symlink to the -same directory, or the initial -.Ev PWD -value followed a symbolic link, then the cached value may not -be the absolute path. -.Pp -The builtin command may differ from the program of the same name because -the program will use -.Ev PWD -and the builtin uses a separately cached value. -.It Xo read Op Fl p Ar prompt -.Op Fl r -.Ar variable -.Op Ar ... -.Xc -The prompt is printed if the -.Fl p -option is specified and the standard input is a terminal. -Then a line is read from the standard input. -The trailing newline is deleted from the -line and the line is split as described in the section on word splitting -above, and the pieces are assigned to the variables in order. -If there are more pieces than variables, the remaining pieces -(along with the characters in -.Ev IFS -that separated them) are assigned to the last variable. -If there are more variables than pieces, -the remaining variables are assigned the null string. -The -.Ic read -builtin will indicate success unless EOF is encountered on input, in -which case failure is returned. -.Pp -By default, unless the -.Fl r -option is specified, the backslash -.Dq \e -acts as an escape character, causing the following character to be treated -literally. -If a backslash is followed by a newline, the backslash and the -newline will be deleted. -.It readonly Ar name ... -.It readonly Fl p -The specified names are marked as read only, so that they cannot be -subsequently modified or unset. -The shell allows the value of a variable -to be set at the same time it is marked read only by writing -.Pp -.Dl readonly name=value -.Pp -With no arguments the readonly command lists the names of all read only -variables. -With the -.Fl p -option specified the output will be formatted suitably for non-interactive use. -.Pp -.It Xo set -.Oo { -.Fl options | Cm +options | Cm -- } -.Oc Ar arg ... -.Xc -The -.Ic set -command performs three different functions. -.Pp -With no arguments, it lists the values of all shell variables. -.Pp -If options are given, it sets the specified option -flags, or clears them as described in the section called -.Sx Argument List Processing . -.Pp -The third use of the set command is to set the values of the shell's -positional parameters to the specified args. -To change the positional -parameters without changing any options, use -.Dq -- -as the first argument to set. -If no args are present, the set command -will clear all the positional parameters (equivalent to executing -.Dq shift $# . ) -.It setvar Ar variable Ar value -Assigns value to variable. -(In general it is better to write -variable=value rather than using -.Ic setvar . -.Ic setvar -is intended to be used in -functions that assign values to variables whose names are passed as -parameters.) -.It shift Op Ar n -Shift the positional parameters n times. -A -.Ic shift -sets the value of -.Va $1 -to the value of -.Va $2 , -the value of -.Va $2 -to the value of -.Va $3 , -and so on, decreasing -the value of -.Va $# -by one. -If there are zero positional parameters, -.Ic shift -does nothing. -.It Xo trap -.Op Fl l -.Xc -.It Xo trap -.Op Ar action -.Ar signal ... -.Xc -Cause the shell to parse and execute action when any of the specified -signals are received. -The signals are specified by signal number or as the name of the signal. -If -.Ar signal -is -.Li 0 , -the action is executed when the shell exits. -.Ar action -may be null, which cause the specified signals to be ignored. -With -.Ar action -omitted or set to `-' the specified signals are set to their default action. -When the shell forks off a subshell, it resets trapped (but not ignored) -signals to the default action. -The -.Ic trap -command has no effect on signals that were -ignored on entry to the shell. -Issuing -.Ic trap -with option -.Ar -l -will print a list of valid signal names. -.Ic trap -without any arguments cause it to write a list of signals and their -associated action to the standard output in a format that is suitable -as an input to the shell that achieves the same trapping results. -.Pp -Examples: -.Pp -.Dl trap -.Pp -List trapped signals and their corresponding action -.Pp -.Dl trap -l -.Pp -Print a list of valid signals -.Pp -.Dl trap '' INT QUIT tstp 30 -.Pp -Ignore signals INT QUIT TSTP USR1 -.Pp -.Dl trap date INT -.Pp -Print date upon receiving signal INT -.It type Op Ar name ... -Interpret each name as a command and print the resolution of the command -search. -Possible resolutions are: -shell keyword, alias, shell builtin, -command, tracked alias and not found. -For aliases the alias expansion is -printed; for commands and tracked aliases the complete pathname of the -command is printed. -.It ulimit Xo -.Op Fl H \*(Ba Fl S -.Op Fl a \*(Ba Fl tfdscmlpn Op Ar value -.Xc -Inquire about or set the hard or soft limits on processes or set new -limits. -The choice between hard limit (which no process is allowed to -violate, and which may not be raised once it has been lowered) and soft -limit (which causes processes to be signaled but not necessarily killed, -and which may be raised) is made with these flags: -.Bl -tag -width Fl -.It Fl H -set or inquire about hard limits -.It Fl S -set or inquire about soft limits. -If neither -.Fl H -nor -.Fl S -is specified, the soft limit is displayed or both limits are set. -If both are specified, the last one wins. -.El -.Pp -.Bl -tag -width Fl -The limit to be interrogated or set, then, is chosen by specifying -any one of these flags: -.It Fl a -show all the current limits -.It Fl b -show or set the limit on the socket buffer size of a process (in bytes) -.It Fl t -show or set the limit on CPU time (in seconds) -.It Fl f -show or set the limit on the largest file that can be created -(in 512-byte blocks) -.It Fl d -show or set the limit on the data segment size of a process (in kilobytes) -.It Fl s -show or set the limit on the stack size of a process (in kilobytes) -.It Fl c -show or set the limit on the largest core dump size that can be produced -(in 512-byte blocks) -.It Fl m -show or set the limit on the total physical memory that can be -in use by a process (in kilobytes) -.It Fl l -show or set the limit on how much memory a process can lock with -.Xr mlock 2 -(in kilobytes) -.It Fl p -show or set the limit on the number of processes this user can -have at one time -.It Fl n -show or set the limit on the number of files a process can have open at once -.El -.Pp -If none of these is specified, it is the limit on file size that is shown -or set. -If value is specified, the limit is set to that number; otherwise -the current limit is displayed. -.Pp -Limits of an arbitrary process can be displayed or set using the -.Xr sysctl 8 -utility. -.Pp -.It umask Op Ar mask -Set the value of umask (see -.Xr umask 2 ) -to the specified octal value. -If the argument is omitted, the umask value is printed. -.It unalias Xo -.Op Fl a -.Op Ar name -.Xc -If -.Ar name -is specified, the shell removes that alias. -If -.Fl a -is specified, all aliases are removed. -.It unset Ar name ... -The specified variables and functions are unset and unexported. -If a given name corresponds to both a variable and a function, both -the variable and the function are unset. -.It wait Op Ar job -Wait for the specified job to complete and return the exit status of the -last process in the job. -If the argument is omitted, wait for all jobs to -complete and then return an exit status of zero. -.El -.Ss Command Line Editing -When -.Nm -is being used interactively from a terminal, the current command -and the command history (see -.Ic fc -in -.Sx Builtins ) -can be edited using emacs-mode or vi-mode command-line editing. -The command -.Ql set -o emacs -enables emacs-mode editing. -The command -.Ql set -o vi -enables vi-mode editing and places sh into vi insert mode. -(See the -.Sx Argument List Processing -section above.) -.Pp -The vi mode uses commands similar to a subset of those described in the -.Xr vi 1 -man page. -With vi-mode -enabled, sh can be switched between insert mode and command mode. -It's similar to vi: typing -.Aq ESC -will throw you into command VI command mode. -Hitting -.Aq return -while in command mode will pass the line to the shell. -.Pp -The emacs mode uses commands similar to a subset available in -the emacs editor. -With emacs-mode enabled, special keys can be used to modify the text -in the buffer using the control key. -.Pp -.Nm -uses the -.Xr editline 3 -library. -.Sh EXIT STATUS -Errors that are detected by the shell, such as a syntax error, will cause the -shell to exit with a non-zero exit status. -If the shell is not an -interactive shell, the execution of the shell file will be aborted. -Otherwise -the shell will return the exit status of the last command executed, or -if the exit builtin is used with a numeric argument, it will return the -argument. -.Sh ENVIRONMENT -.Bl -tag -width MAILCHECK -.It Ev HOME -Set automatically by -.Xr login 1 -from the user's login directory in the password file -.Pq Xr passwd 5 . -This environment variable also functions as the default argument for the -cd builtin. -.It Ev PATH -The default search path for executables. -See the above section -.Sx Path Search . -.It Ev CDPATH -The search path used with the cd builtin. -.It Ev LANG -The string used to specify localization information that allows users -to work with different culture-specific and language conventions. -See -.Xr nls 7 . -.It Ev MAIL -The name of a mail file, that will be checked for the arrival of new mail. -Overridden by -.Ev MAILPATH . -.It Ev MAILCHECK -The frequency in seconds that the shell checks for the arrival of mail -in the files specified by the -.Ev MAILPATH -or the -.Ev MAIL -file. -If set to 0, the check will occur at each prompt. -.It Ev MAILPATH -A colon -.Dq \&: -separated list of file names, for the shell to check for incoming mail. -This environment setting overrides the -.Ev MAIL -setting. -There is a maximum of 10 mailboxes that can be monitored at once. -.It Ev PS1 -The primary prompt string, which defaults to -.Dq $ \ , -unless you are the superuser, in which case it defaults to -.Dq # \ . -.It Ev PS2 -The secondary prompt string, which defaults to -.Dq \*[Gt] \ . -.It Ev PS4 -Output before each line when execution trace (set -x) is enabled, -defaults to -.Dq + \ . -.It Ev IFS -Input Field Separators. -This is normally set to -.Aq space , -.Aq tab , -and -.Aq newline . -See the -.Sx White Space Splitting -section for more details. -.It Ev TERM -The default terminal setting for the shell. -This is inherited by -children of the shell, and is used in the history editing modes. -.It Ev HISTSIZE -The number of lines in the history buffer for the shell. -.El -.Sh FILES -.Bl -item -width HOMEprofilexxxx -.It -.Pa $HOME/.profile -.It -.Pa /etc/profile -.El -.Sh SEE ALSO -.Xr csh 1 , -.Xr echo 1 , -.Xr getopt 1 , -.Xr ksh 1 , -.Xr login 1 , -.Xr printf 1 , -.Xr test 1 , -.Xr editline 3 , -.Xr getopt 3 , -.\" .Xr profile 4 , -.Xr editrc 5 , -.Xr passwd 5 , -.Xr environ 7 , -.Xr nls 7 , -.Xr sysctl 8 -.Sh HISTORY -A -.Nm -command appeared in -.At v1 . -It was, however, unmaintainable so we wrote this one. -.Sh BUGS -Setuid shell scripts should be avoided at all costs, as they are a -significant security risk. -.Pp -PS1, PS2, and PS4 should be subject to parameter expansion before -being displayed. diff --git a/sh/shell.h b/sh/shell.h deleted file mode 100644 index 94be27ae267039ee4ce8aff1c6f628f35e6cab7d..0000000000000000000000000000000000000000 --- a/sh/shell.h +++ /dev/null @@ -1,83 +0,0 @@ -/* $NetBSD: shell.h,v 1.17 2003/08/07 09:05:38 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)shell.h 8.2 (Berkeley) 5/4/95 - */ - -/* - * The follow should be set to reflect the type of system you have: - * JOBS -> 1 if you have Berkeley job control, 0 otherwise. - * SHORTNAMES -> 1 if your linker cannot handle long names. - * define BSD if you are running 4.2 BSD or later. - * define SYSV if you are running under System V. - * define DEBUG=1 to compile in debugging ('set -o debug' to turn on) - * define DEBUG=2 to compile in and turn on debugging. - * define DO_SHAREDVFORK to indicate that vfork(2) shares its address - * with its parent. - * - * When debugging is on, debugging info will be written to ./trace and - * a quit signal will generate a core dump. - */ - -#include <sys/param.h> - -#define JOBS 1 -#ifndef BSD -#define BSD 1 -#endif - -#ifndef DO_SHAREDVFORK -#if __NetBSD_Version__ >= 104000000 -#define DO_SHAREDVFORK -#endif -#endif - -typedef void *pointer; -#ifndef NULL -#define NULL (void *)0 -#endif -#define STATIC /* empty */ -#define MKINIT /* empty */ - -#include <sys/cdefs.h> - -extern char nullstr[1]; /* null string */ - - -#ifdef DEBUG -#define TRACE(param) trace param -#define TRACEV(param) tracev param -#else -#define TRACE(param) -#define TRACEV(param) -#endif diff --git a/sh/show.c b/sh/show.c deleted file mode 100644 index e92aa51dd7792aafb26b1224d5de7d617c6e0263..0000000000000000000000000000000000000000 --- a/sh/show.c +++ /dev/null @@ -1,425 +0,0 @@ -/* $NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $"); -#endif -#endif /* not lint */ - -#include <stdio.h> -#include <stdarg.h> -#include <stdlib.h> - -#include "shell.h" -#include "parser.h" -#include "nodes.h" -#include "mystring.h" -#include "show.h" -#include "options.h" - - -#ifdef DEBUG -static void shtree(union node *, int, char *, FILE*); -static void shcmd(union node *, FILE *); -static void sharg(union node *, FILE *); -static void indent(int, char *, FILE *); -static void trstring(char *); - - -void -showtree(union node *n) -{ - trputs("showtree called\n"); - shtree(n, 1, NULL, stdout); -} - - -static void -shtree(union node *n, int ind, char *pfx, FILE *fp) -{ - struct nodelist *lp; - const char *s; - - if (n == NULL) - return; - - indent(ind, pfx, fp); - switch(n->type) { - case NSEMI: - s = "; "; - goto binop; - case NAND: - s = " && "; - goto binop; - case NOR: - s = " || "; -binop: - shtree(n->nbinary.ch1, ind, NULL, fp); - /* if (ind < 0) */ - fputs(s, fp); - shtree(n->nbinary.ch2, ind, NULL, fp); - break; - case NCMD: - shcmd(n, fp); - if (ind >= 0) - putc('\n', fp); - break; - case NPIPE: - for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { - shcmd(lp->n, fp); - if (lp->next) - fputs(" | ", fp); - } - if (n->npipe.backgnd) - fputs(" &", fp); - if (ind >= 0) - putc('\n', fp); - break; - default: - fprintf(fp, "<node type %d>", n->type); - if (ind >= 0) - putc('\n', fp); - break; - } -} - - - -static void -shcmd(union node *cmd, FILE *fp) -{ - union node *np; - int first; - const char *s; - int dftfd; - - first = 1; - for (np = cmd->ncmd.args ; np ; np = np->narg.next) { - if (! first) - putchar(' '); - sharg(np, fp); - first = 0; - } - for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { - if (! first) - putchar(' '); - switch (np->nfile.type) { - case NTO: s = ">"; dftfd = 1; break; - case NCLOBBER: s = ">|"; dftfd = 1; break; - case NAPPEND: s = ">>"; dftfd = 1; break; - case NTOFD: s = ">&"; dftfd = 1; break; - case NFROM: s = "<"; dftfd = 0; break; - case NFROMFD: s = "<&"; dftfd = 0; break; - case NFROMTO: s = "<>"; dftfd = 0; break; - default: s = "*error*"; dftfd = 0; break; - } - if (np->nfile.fd != dftfd) - fprintf(fp, "%d", np->nfile.fd); - fputs(s, fp); - if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { - fprintf(fp, "%d", np->ndup.dupfd); - } else { - sharg(np->nfile.fname, fp); - } - first = 0; - } -} - - - -static void -sharg(union node *arg, FILE *fp) -{ - char *p; - struct nodelist *bqlist; - int subtype; - - if (arg->type != NARG) { - printf("<node type %d>\n", arg->type); - abort(); - } - bqlist = arg->narg.backquote; - for (p = arg->narg.text ; *p ; p++) { - switch (*p) { - case CTLESC: - putc(*++p, fp); - break; - case CTLVAR: - putc('$', fp); - putc('{', fp); - subtype = *++p; - if (subtype == VSLENGTH) - putc('#', fp); - - while (*p != '=') - putc(*p++, fp); - - if (subtype & VSNUL) - putc(':', fp); - - switch (subtype & VSTYPE) { - case VSNORMAL: - putc('}', fp); - break; - case VSMINUS: - putc('-', fp); - break; - case VSPLUS: - putc('+', fp); - break; - case VSQUESTION: - putc('?', fp); - break; - case VSASSIGN: - putc('=', fp); - break; - case VSTRIMLEFT: - putc('#', fp); - break; - case VSTRIMLEFTMAX: - putc('#', fp); - putc('#', fp); - break; - case VSTRIMRIGHT: - putc('%', fp); - break; - case VSTRIMRIGHTMAX: - putc('%', fp); - putc('%', fp); - break; - case VSLENGTH: - break; - default: - printf("<subtype %d>", subtype); - } - break; - case CTLENDVAR: - putc('}', fp); - break; - case CTLBACKQ: - case CTLBACKQ|CTLQUOTE: - putc('$', fp); - putc('(', fp); - shtree(bqlist->n, -1, NULL, fp); - putc(')', fp); - break; - default: - putc(*p, fp); - break; - } - } -} - - -static void -indent(int amount, char *pfx, FILE *fp) -{ - int i; - - for (i = 0 ; i < amount ; i++) { - if (pfx && i == amount - 1) - fputs(pfx, fp); - putc('\t', fp); - } -} -#endif - - - -/* - * Debugging stuff. - */ - - -FILE *tracefile; - - -#ifdef DEBUG -void -trputc(int c) -{ - if (debug != 1) - return; - putc(c, tracefile); -} -#endif - -void -trace(const char *fmt, ...) -{ -#ifdef DEBUG - va_list va; - - if (debug != 1) - return; - va_start(va, fmt); - (void) vfprintf(tracefile, fmt, va); - va_end(va); -#endif -} - -void -tracev(const char *fmt, va_list va) -{ -#ifdef DEBUG - if (debug != 1) - return; - (void) vfprintf(tracefile, fmt, va); -#endif -} - - -#ifdef DEBUG -void -trputs(const char *s) -{ - if (debug != 1) - return; - fputs(s, tracefile); -} - - -static void -trstring(char *s) -{ - char *p; - char c; - - if (debug != 1) - return; - putc('"', tracefile); - for (p = s ; *p ; p++) { - switch (*p) { - case '\n': c = 'n'; goto backslash; - case '\t': c = 't'; goto backslash; - case '\r': c = 'r'; goto backslash; - case '"': c = '"'; goto backslash; - case '\\': c = '\\'; goto backslash; - case CTLESC: c = 'e'; goto backslash; - case CTLVAR: c = 'v'; goto backslash; - case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; - case CTLBACKQ: c = 'q'; goto backslash; - case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; -backslash: putc('\\', tracefile); - putc(c, tracefile); - break; - default: - if (*p >= ' ' && *p <= '~') - putc(*p, tracefile); - else { - putc('\\', tracefile); - putc(*p >> 6 & 03, tracefile); - putc(*p >> 3 & 07, tracefile); - putc(*p & 07, tracefile); - } - break; - } - } - putc('"', tracefile); -} -#endif - - -void -trargs(char **ap) -{ -#ifdef DEBUG - if (debug != 1) - return; - while (*ap) { - trstring(*ap++); - if (*ap) - putc(' ', tracefile); - else - putc('\n', tracefile); - } -#endif -} - - -#ifdef DEBUG -void -opentrace(void) -{ - char s[100]; -#ifdef O_APPEND - int flags; -#endif - - if (debug != 1) { - if (tracefile) - fflush(tracefile); - /* leave open because libedit might be using it */ - return; - } -#ifdef not_this_way - { - char *p; - if ((p = getenv("HOME")) == NULL) { - if (geteuid() == 0) - p = "/"; - else - p = "/tmp"; - } - scopy(p, s); - strcat(s, "/trace"); - } -#else - scopy("./trace", s); -#endif /* not_this_way */ - if (tracefile) { - if (!freopen(s, "a", tracefile)) { - fprintf(stderr, "Can't re-open %s\n", s); - debug = 0; - return; - } - } else { - if ((tracefile = fopen(s, "a")) == NULL) { - fprintf(stderr, "Can't open %s\n", s); - debug = 0; - return; - } - } -#ifdef O_APPEND - if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) - fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); -#endif - setlinebuf(tracefile); - fputs("\nTracing started.\n", tracefile); -} -#endif /* DEBUG */ diff --git a/sh/show.h b/sh/show.h deleted file mode 100644 index 3152ff277f3659a66ed9962f1a5ec483b185dd04..0000000000000000000000000000000000000000 --- a/sh/show.h +++ /dev/null @@ -1,45 +0,0 @@ -/* $NetBSD: show.h,v 1.7 2003/08/07 09:05:38 agc Exp $ */ - -/*- - * Copyright (c) 1995 - * 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. - * 3. 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. - * - * @(#)show.h 1.1 (Berkeley) 5/4/95 - */ - -#include <stdarg.h> - -union node; -void showtree(union node *); -void trace(const char *, ...); -void tracev(const char *, va_list); -void trargs(char **); -#ifdef DEBUG -void trputc(int); -void trputs(const char *); -void opentrace(void); -#endif diff --git a/sh/syntax.c b/sh/syntax.c deleted file mode 100644 index 094f6745d5ab4e5642b64dddd1ef92a201ee72fc..0000000000000000000000000000000000000000 --- a/sh/syntax.c +++ /dev/null @@ -1,102 +0,0 @@ -/* $NetBSD: syntax.c,v 1.1 2004/01/17 17:38:12 dsl Exp $ */ - -#include "shell.h" -#include "syntax.h" -#include "parser.h" -#include <limits.h> - -#if CWORD != 0 -#error initialisation assumes 'CWORD' is zero -#endif - -#define ndx(ch) (ch + 1 - CHAR_MIN) -#define set(ch, val) [ndx(ch)] = val, -#define set_range(s, e, val) [ndx(s) ... ndx(e)] = val, - -/* syntax table used when not in quotes */ -const char basesyntax[257] = { CEOF, - set_range(CTL_FIRST, CTL_LAST, CCTL) - set('\n', CNL) - set('\\', CBACK) - set('\'', CSQUOTE) - set('"', CDQUOTE) - set('`', CBQUOTE) - set('$', CVAR) - set('}', CENDVAR) - set('<', CSPCL) - set('>', CSPCL) - set('(', CSPCL) - set(')', CSPCL) - set(';', CSPCL) - set('&', CSPCL) - set('|', CSPCL) - set(' ', CSPCL) - set('\t', CSPCL) -}; - -/* syntax table used when in double quotes */ -const char dqsyntax[257] = { CEOF, - set_range(CTL_FIRST, CTL_LAST, CCTL) - set('\n', CNL) - set('\\', CBACK) - set('"', CDQUOTE) - set('`', CBQUOTE) - set('$', CVAR) - set('}', CENDVAR) - /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ - set('!', CCTL) - set('*', CCTL) - set('?', CCTL) - set('[', CCTL) - set('=', CCTL) - set('~', CCTL) - set(':', CCTL) - set('/', CCTL) - set('-', CCTL) -}; - -/* syntax table used when in single quotes */ -const char sqsyntax[257] = { CEOF, - set_range(CTL_FIRST, CTL_LAST, CCTL) - set('\n', CNL) - set('\'', CSQUOTE) - /* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ - set('!', CCTL) - set('*', CCTL) - set('?', CCTL) - set('[', CCTL) - set('=', CCTL) - set('~', CCTL) - set(':', CCTL) - set('/', CCTL) - set('-', CCTL) -}; - -/* syntax table used when in arithmetic */ -const char arisyntax[257] = { CEOF, - set_range(CTL_FIRST, CTL_LAST, CCTL) - set('\n', CNL) - set('\\', CBACK) - set('`', CBQUOTE) - set('\'', CSQUOTE) - set('"', CDQUOTE) - set('$', CVAR) - set('}', CENDVAR) - set('(', CLP) - set(')', CRP) -}; - -/* character classification table */ -const char is_type[257] = { 0, - set_range('0', '9', ISDIGIT) - set_range('a', 'z', ISLOWER) - set_range('A', 'Z', ISUPPER) - set('_', ISUNDER) - set('#', ISSPECL) - set('?', ISSPECL) - set('$', ISSPECL) - set('!', ISSPECL) - set('-', ISSPECL) - set('*', ISSPECL) - set('@', ISSPECL) -}; diff --git a/sh/syntax.h b/sh/syntax.h deleted file mode 100644 index 89a32dcdc76d8c8aa0812a24a3ae41622c31d104..0000000000000000000000000000000000000000 --- a/sh/syntax.h +++ /dev/null @@ -1,83 +0,0 @@ -/* $NetBSD: syntax.h,v 1.2 2004/01/17 17:38:12 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#include <ctype.h> - -/* Syntax classes */ -#define CWORD 0 /* character is nothing special */ -#define CNL 1 /* newline character */ -#define CBACK 2 /* a backslash character */ -#define CSQUOTE 3 /* single quote */ -#define CDQUOTE 4 /* double quote */ -#define CBQUOTE 5 /* backwards single quote */ -#define CVAR 6 /* a dollar sign */ -#define CENDVAR 7 /* a '}' character */ -#define CLP 8 /* a left paren in arithmetic */ -#define CRP 9 /* a right paren in arithmetic */ -#define CEOF 10 /* end of file */ -#define CCTL 11 /* like CWORD, except it must be escaped */ -#define CSPCL 12 /* these terminate a word */ - -/* Syntax classes for is_ functions */ -#define ISDIGIT 01 /* a digit */ -#define ISUPPER 02 /* an upper case letter */ -#define ISLOWER 04 /* a lower case letter */ -#define ISUNDER 010 /* an underscore */ -#define ISSPECL 020 /* the name of a special parameter */ - -#define PEOF (CHAR_MIN - 1) -#define SYNBASE (-PEOF) -/* XXX UPEOF is CHAR_MAX, so is a valid 'char' value... */ -#define UPEOF ((char)PEOF) - - -#define BASESYNTAX (basesyntax + SYNBASE) -#define DQSYNTAX (dqsyntax + SYNBASE) -#define SQSYNTAX (sqsyntax + SYNBASE) -#define ARISYNTAX (arisyntax + SYNBASE) - -/* These defines assume that the digits are contiguous */ -#define is_digit(c) ((unsigned)((c) - '0') <= 9) -#define is_alpha(c) (((char)(c)) != UPEOF && ((c) < CTL_FIRST || (c) > CTL_LAST) && isalpha((unsigned char)(c))) -#define is_name(c) (((char)(c)) != UPEOF && ((c) < CTL_FIRST || (c) > CTL_LAST) && ((c) == '_' || isalpha((unsigned char)(c)))) -#define is_in_name(c) (((char)(c)) != UPEOF && ((c) < CTL_FIRST || (c) > CTL_LAST) && ((c) == '_' || isalnum((unsigned char)(c)))) -#define is_special(c) ((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT)) -#define digit_val(c) ((c) - '0') - -extern const char basesyntax[]; -extern const char dqsyntax[]; -extern const char sqsyntax[]; -extern const char arisyntax[]; -extern const char is_type[]; diff --git a/sh/token.h b/sh/token.h deleted file mode 100644 index c961f0184fb66ed6c8be346ffe278036547e309f..0000000000000000000000000000000000000000 --- a/sh/token.h +++ /dev/null @@ -1,112 +0,0 @@ -#define TEOF 0 -#define TNL 1 -#define TSEMI 2 -#define TBACKGND 3 -#define TAND 4 -#define TOR 5 -#define TPIPE 6 -#define TLP 7 -#define TRP 8 -#define TENDCASE 9 -#define TENDBQUOTE 10 -#define TREDIR 11 -#define TWORD 12 -#define TIF 13 -#define TTHEN 14 -#define TELSE 15 -#define TELIF 16 -#define TFI 17 -#define TWHILE 18 -#define TUNTIL 19 -#define TFOR 20 -#define TDO 21 -#define TDONE 22 -#define TBEGIN 23 -#define TEND 24 -#define TCASE 25 -#define TESAC 26 -#define TNOT 27 - -/* Array indicating which tokens mark the end of a list */ -const char tokendlist[] = { - 1, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 1, - 1, - 1, - 0, - 0, - 0, - 1, - 1, - 1, - 1, - 0, - 0, - 0, - 1, - 1, - 0, - 1, - 0, - 1, - 0, -}; - -const char *const tokname[] = { - "end of file", - "newline", - "\";\"", - "\"&\"", - "\"&&\"", - "\"||\"", - "\"|\"", - "\"(\"", - "\")\"", - "\";;\"", - "\"`\"", - "redirection", - "word", - "\"if\"", - "\"then\"", - "\"else\"", - "\"elif\"", - "\"fi\"", - "\"while\"", - "\"until\"", - "\"for\"", - "\"do\"", - "\"done\"", - "\"{\"", - "\"}\"", - "\"case\"", - "\"esac\"", - "\"!\"", -}; - -#define KWDOFFSET 13 - -const char *const parsekwd[] = { - "if", - "then", - "else", - "elif", - "fi", - "while", - "until", - "for", - "do", - "done", - "{", - "}", - "case", - "esac", - "!", - 0 -}; diff --git a/sh/trap.c b/sh/trap.c deleted file mode 100644 index b3b2db414a2637e96bbd567cdb869331a48ef3ab..0000000000000000000000000000000000000000 --- a/sh/trap.c +++ /dev/null @@ -1,470 +0,0 @@ -/* $NetBSD: trap.c,v 1.31 2005/01/11 19:38:57 christos Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; -#else -__RCSID("$NetBSD: trap.c,v 1.31 2005/01/11 19:38:57 christos Exp $"); -#endif -#endif /* not lint */ - -#include <signal.h> -#include <unistd.h> -#include <stdlib.h> - -#include "shell.h" -#include "main.h" -#include "nodes.h" /* for other headers */ -#include "eval.h" -#include "jobs.h" -#include "show.h" -#include "options.h" -#include "syntax.h" -#include "output.h" -#include "memalloc.h" -#include "error.h" -#include "trap.h" -#include "mystring.h" -#include "var.h" - -static const char *sys_signame[NSIG] = { - "Unused", - "HUP", "INT", "QUIT", "ILL", - "TRAP", "ABRT", "BUS", "FPE", - "KILL", "USR1", "SEGV", "USR2", - "PIPE", "ALRM", "TERM", - "Unknown", - "CHLD", - "CONT", "STOP", "TSTP", "TTIN", - "TTOU", "URG", "XCPU", "XFSZ", - "VTALRM", "PROF", "WINCH", "IO", - "PWR", "SYS" -}; - -/* - * Sigmode records the current value of the signal handlers for the various - * modes. A value of zero means that the current handler is not known. - * S_HARD_IGN indicates that the signal was ignored on entry to the shell, - */ - -#define S_DFL 1 /* default signal handling (SIG_DFL) */ -#define S_CATCH 2 /* signal is caught */ -#define S_IGN 3 /* signal is ignored (SIG_IGN) */ -#define S_HARD_IGN 4 /* signal is ignored permenantly */ -#define S_RESET 5 /* temporary - to reset a hard ignored sig */ - - -char *trap[NSIG+1]; /* trap handler commands */ -MKINIT char sigmode[NSIG]; /* current value of signal */ -char gotsig[NSIG]; /* indicates specified signal received */ -int pendingsigs; /* indicates some signal received */ - -static int getsigaction(int, sig_t *); - -/* - * return the signal number described by `p' (as a number or a name) - * or -1 if it isn't one - */ - -static int -signame_to_signum(const char *p) -{ - int i; - - if (is_number(p)) - return number(p); - - if (strcasecmp(p, "exit") == 0 ) - return 0; - - if (strncasecmp(p, "sig", 3) == 0) - p += 3; - - for (i = 0; i < NSIG; ++i) - if (strcasecmp (p, sys_signame[i]) == 0) - return i; - return -1; -} - -/* - * Print a list of valid signal names - */ -static void -printsignals(void) -{ - int n; - - out1str("EXIT "); - - for (n = 1; n < NSIG; n++) { - out1fmt("%s", sys_signame[n]); - if ((n == NSIG/2) || n == (NSIG - 1)) - out1str("\n"); - else - out1c(' '); - } -} - -/* - * The trap builtin. - */ - -int -trapcmd(int argc, char **argv) -{ - char *action; - char **ap; - int signo; - - if (argc <= 1) { - for (signo = 0 ; signo <= NSIG ; signo++) - if (trap[signo] != NULL) { - out1fmt("trap -- "); - print_quoted(trap[signo]); - out1fmt(" %s\n", - (signo) ? sys_signame[signo] : "EXIT"); - } - return 0; - } - ap = argv + 1; - - action = NULL; - - if (strcmp(*ap, "--") == 0) - if (*++ap == NULL) - return 0; - - if (signame_to_signum(*ap) == -1) { - if ((*ap)[0] == '-') { - if ((*ap)[1] == '\0') - ap++; - else if ((*ap)[1] == 'l' && (*ap)[2] == '\0') { - printsignals(); - return 0; - } - else - error("bad option %s\n", *ap); - } - else - action = *ap++; - } - - while (*ap) { - if (is_number(*ap)) - signo = number(*ap); - else - signo = signame_to_signum(*ap); - - if (signo < 0 || signo > NSIG) - error("%s: bad trap", *ap); - - INTOFF; - if (action) - action = savestr(action); - - if (trap[signo]) - ckfree(trap[signo]); - - trap[signo] = action; - - if (signo != 0) - setsignal(signo, 0); - INTON; - ap++; - } - return 0; -} - - - -/* - * Clear traps on a fork or vfork. - * Takes one arg vfork, to tell it to not be destructive of - * the parents variables. - */ - -void -clear_traps(int vforked) -{ - char **tp; - - for (tp = trap ; tp <= &trap[NSIG] ; tp++) { - if (*tp && **tp) { /* trap not NULL or SIG_IGN */ - INTOFF; - if (!vforked) { - ckfree(*tp); - *tp = NULL; - } - if (tp != &trap[0]) - setsignal(tp - trap, vforked); - INTON; - } - } -} - - - -/* - * Set the signal handler for the specified signal. The routine figures - * out what it should be set to. - */ - -long -setsignal(int signo, int vforked) -{ - int action; - sig_t sigact = SIG_DFL; - struct sigaction act, oact; - char *t, tsig; - - if ((t = trap[signo]) == NULL) - action = S_DFL; - else if (*t != '\0') - action = S_CATCH; - else - action = S_IGN; - if (rootshell && !vforked && action == S_DFL) { - switch (signo) { - case SIGINT: - if (iflag || minusc || sflag == 0) - action = S_CATCH; - break; - case SIGQUIT: -#ifdef DEBUG - if (debug) - break; -#endif - /* FALLTHROUGH */ - case SIGTERM: - if (iflag) - action = S_IGN; - break; -#if JOBS - case SIGTSTP: - case SIGTTOU: - if (mflag) - action = S_IGN; - break; -#endif - } - } - - t = &sigmode[signo - 1]; - tsig = *t; - if (tsig == 0) { - /* - * current setting unknown - */ - if (!getsigaction(signo, &sigact)) { - /* - * Pretend it worked; maybe we should give a warning - * here, but other shells don't. We don't alter - * sigmode, so that we retry every time. - */ - return 0; - } - if (sigact == SIG_IGN) { - if (mflag && (signo == SIGTSTP || - signo == SIGTTIN || signo == SIGTTOU)) { - tsig = S_IGN; /* don't hard ignore these */ - } else - tsig = S_HARD_IGN; - } else { - tsig = S_RESET; /* force to be set */ - } - } - if (tsig == S_HARD_IGN || tsig == action) - return 0; - switch (action) { - case S_DFL: sigact = SIG_DFL; break; - case S_CATCH: sigact = onsig; break; - case S_IGN: sigact = SIG_IGN; break; - } - if (!vforked) - *t = action; - act.sa_handler = sigact; - sigemptyset(&act.sa_mask); - act.sa_flags = 0; -#ifdef SA_INTERRUPT - act.sa_flags |= SA_INTERRUPT; -#endif - if(sigaction(signo, &act, &oact) < 0) - return (long) SIG_ERR; - return (long) oact.sa_handler; -} - -/* - * Return the current setting for sig w/o changing it. - */ -static int -getsigaction(int signo, sig_t *sigact) -{ - struct sigaction sa; - - if (sigaction(signo, (struct sigaction *)0, &sa) == -1) - return 0; - *sigact = (sig_t) sa.sa_handler; - return 1; -} - -/* - * Ignore a signal. - */ - -void -ignoresig(int signo, int vforked) -{ - if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) - bsd_signal(signo, SIG_IGN); - if (!vforked) - sigmode[signo - 1] = S_HARD_IGN; -} - - -#ifdef mkinit -INCLUDE <signal.h> -INCLUDE "trap.h" - -SHELLPROC { - char *sm; - - clear_traps(0); - for (sm = sigmode ; sm < sigmode + NSIG ; sm++) { - if (*sm == S_IGN) - *sm = S_HARD_IGN; - } -} -#endif - - - -/* - * Signal handler. - */ - -void -onsig(int signo) -{ - bsd_signal(signo, onsig); - if (signo == SIGINT && trap[SIGINT] == NULL) { - onint(); - return; - } - gotsig[signo - 1] = 1; - pendingsigs++; -} - - - -/* - * Called to execute a trap. Perhaps we should avoid entering new trap - * handlers while we are executing a trap handler. - */ - -void -dotrap(void) -{ - int i; - int savestatus; - - for (;;) { - for (i = 1 ; ; i++) { - if (gotsig[i - 1]) - break; - if (i >= NSIG) - goto done; - } - gotsig[i - 1] = 0; - savestatus=exitstatus; - evalstring(trap[i], 0); - exitstatus=savestatus; - } -done: - pendingsigs = 0; -} - - - -/* - * Controls whether the shell is interactive or not. - */ - - -void -setinteractive(int on) -{ - static int is_interactive; - - if (on == is_interactive) - return; - setsignal(SIGINT, 0); - setsignal(SIGQUIT, 0); - setsignal(SIGTERM, 0); - is_interactive = on; -} - - - -/* - * Called to exit the shell. - */ - -void -exitshell(int status) -{ - struct jmploc loc1, loc2; - char *p; - - TRACE(("pid %d, exitshell(%d)\n", getpid(), status)); - if (setjmp(loc1.loc)) { - goto l1; - } - if (setjmp(loc2.loc)) { - goto l2; - } - handler = &loc1; - if ((p = trap[0]) != NULL && *p != '\0') { - trap[0] = NULL; - evalstring(p, 0); - } -l1: handler = &loc2; /* probably unnecessary */ - flushall(); -#if JOBS - setjobctl(0); -#endif -l2: _exit(status); - /* NOTREACHED */ -} diff --git a/sh/trap.h b/sh/trap.h deleted file mode 100644 index 125ef402ec03e5027c9964a921269199e187486a..0000000000000000000000000000000000000000 --- a/sh/trap.h +++ /dev/null @@ -1,46 +0,0 @@ -/* $NetBSD: trap.h,v 1.17 2003/08/07 09:05:39 agc Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)trap.h 8.3 (Berkeley) 6/5/95 - */ - -extern int pendingsigs; - -int trapcmd(int, char **); -void clear_traps(int); -long setsignal(int, int); -void ignoresig(int, int); -void onsig(int); -void dotrap(void); -void setinteractive(int); -void exitshell(int) __attribute__((__noreturn__)); diff --git a/sh/var.c b/sh/var.c deleted file mode 100644 index a1f1689c31ee0d5f6390f782b6b75e1ca58907e0..0000000000000000000000000000000000000000 --- a/sh/var.c +++ /dev/null @@ -1,825 +0,0 @@ -/* $NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -#if 0 -static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; -#else -__RCSID("$NetBSD: var.c,v 1.36 2004/10/06 10:23:43 enami Exp $"); -#endif -#endif /* not lint */ - -#include <unistd.h> -#include <stdlib.h> -#include <paths.h> - -/* - * Shell variables. - */ - -#include "shell.h" -#include "output.h" -#include "expand.h" -#include "nodes.h" /* for other headers */ -#include "eval.h" /* defines cmdenviron */ -#include "exec.h" -#include "syntax.h" -#include "options.h" -#include "var.h" -#include "memalloc.h" -#include "error.h" -#include "mystring.h" -#include "parser.h" -#include "show.h" -#ifndef SMALL -#include "myhistedit.h" -#endif - -#ifdef SMALL -#define VTABSIZE 39 -#else -#define VTABSIZE 517 -#endif - - -struct varinit { - struct var *var; - int flags; - const char *text; - void (*func)(const char *); -}; - - -#if ATTY -struct var vatty; -#endif -#ifdef WITH_HISTORY -struct var vhistsize; -struct var vterm; -#endif -struct var vifs; -struct var vmpath; -struct var vpath; -struct var vps1; -struct var vps2; -struct var vps4; -struct var vvers; -struct var voptind; - -const struct varinit varinit[] = { -#if ATTY - { &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=", - NULL }, -#endif -#ifdef WITH_HISTORY - { &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", - sethistsize }, -#endif - { &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", - NULL }, - { &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", - NULL }, - { &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH, - changepath }, - /* - * vps1 depends on uid - */ - { &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", - NULL }, - { &vps4, VSTRFIXED|VTEXTFIXED, "PS4=+ ", - NULL }, -#ifdef WITH_HISTORY - { &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", - setterm }, -#endif - { &voptind, VSTRFIXED|VTEXTFIXED|VNOFUNC, "OPTIND=1", - getoptsreset }, - { NULL, 0, NULL, - NULL } -}; - -struct var *vartab[VTABSIZE]; - -STATIC int strequal(const char *, const char *); -STATIC struct var *find_var(const char *, struct var ***, int *); - -/* - * Initialize the varable symbol tables and import the environment - */ - -#ifdef mkinit -INCLUDE "var.h" -MKINIT char **environ; -INIT { - char **envp; - - initvar(); - for (envp = environ ; *envp ; envp++) { - if (strchr(*envp, '=')) { - setvareq(*envp, VEXPORT|VTEXTFIXED); - } - } -} -#endif - - -/* - * This routine initializes the builtin variables. It is called when the - * shell is initialized and again when a shell procedure is spawned. - */ - -void -initvar(void) -{ - const struct varinit *ip; - struct var *vp; - struct var **vpp; - - for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { - if (find_var(ip->text, &vpp, &vp->name_len) != NULL) - continue; - vp->next = *vpp; - *vpp = vp; - vp->text = strdup(ip->text); - vp->flags = ip->flags; - vp->func = ip->func; - } - /* - * PS1 depends on uid - */ - if (find_var("PS1", &vpp, &vps1.name_len) == NULL) { - vps1.next = *vpp; - *vpp = &vps1; - vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# "); - vps1.flags = VSTRFIXED|VTEXTFIXED; - } -} - -/* - * Safe version of setvar, returns 1 on success 0 on failure. - */ - -int -setvarsafe(const char *name, const char *val, int flags) -{ - struct jmploc jmploc; - struct jmploc *volatile savehandler = handler; - int err = 0; -#ifdef __GNUC__ - (void) &err; -#endif - - if (setjmp(jmploc.loc)) - err = 1; - else { - handler = &jmploc; - setvar(name, val, flags); - } - handler = savehandler; - return err; -} - -/* - * Set the value of a variable. The flags argument is ored with the - * flags of the variable. If val is NULL, the variable is unset. - */ - -void -setvar(const char *name, const char *val, int flags) -{ - const char *p; - const char *q; - char *d; - int len; - int namelen; - char *nameeq; - int isbad; - - isbad = 0; - p = name; - if (! is_name(*p)) - isbad = 1; - p++; - for (;;) { - if (! is_in_name(*p)) { - if (*p == '\0' || *p == '=') - break; - isbad = 1; - } - p++; - } - namelen = p - name; - if (isbad) - error("%.*s: bad variable name", namelen, name); - len = namelen + 2; /* 2 is space for '=' and '\0' */ - if (val == NULL) { - flags |= VUNSET; - } else { - len += strlen(val); - } - d = nameeq = ckmalloc(len); - q = name; - while (--namelen >= 0) - *d++ = *q++; - *d++ = '='; - *d = '\0'; - if (val) - scopy(val, d); - setvareq(nameeq, flags); -} - - - -/* - * Same as setvar except that the variable and value are passed in - * the first argument as name=value. Since the first argument will - * be actually stored in the table, it should not be a string that - * will go away. - */ - -void -setvareq(char *s, int flags) -{ - struct var *vp, **vpp; - int nlen; - - if (aflag) - flags |= VEXPORT; - vp = find_var(s, &vpp, &nlen); - if (vp != NULL) { - if (vp->flags & VREADONLY) - error("%.*s: is read only", vp->name_len, s); - if (flags & VNOSET) - return; - INTOFF; - - if (vp->func && (flags & VNOFUNC) == 0) - (*vp->func)(s + vp->name_len + 1); - - if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) - ckfree(vp->text); - - vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); - vp->flags |= flags & ~VNOFUNC; - vp->text = s; - - INTON; - return; - } - /* not found */ - if (flags & VNOSET) - return; - vp = ckmalloc(sizeof (*vp)); - vp->flags = flags & ~VNOFUNC; - vp->text = s; - vp->name_len = nlen; - vp->next = *vpp; - vp->func = NULL; - *vpp = vp; -} - - - -/* - * Process a linked list of variable assignments. - */ - -void -listsetvar(struct strlist *list, int flags) -{ - struct strlist *lp; - - INTOFF; - for (lp = list ; lp ; lp = lp->next) { - setvareq(savestr(lp->text), flags); - } - INTON; -} - -void -listmklocal(struct strlist *list, int flags) -{ - struct strlist *lp; - - for (lp = list ; lp ; lp = lp->next) - mklocal(lp->text, flags); -} - - -/* - * Find the value of a variable. Returns NULL if not set. - */ - -char * -lookupvar(const char *name) -{ - struct var *v; - - v = find_var(name, NULL, NULL); - if (v == NULL || v->flags & VUNSET) - return NULL; - return v->text + v->name_len + 1; -} - - - -/* - * Search the environment of a builtin command. If the second argument - * is nonzero, return the value of a variable even if it hasn't been - * exported. - */ - -char * -bltinlookup(const char *name, int doall) -{ - struct strlist *sp; - struct var *v; - - for (sp = cmdenviron ; sp ; sp = sp->next) { - if (strequal(sp->text, name)) - return strchr(sp->text, '=') + 1; - } - - v = find_var(name, NULL, NULL); - - if (v == NULL || v->flags & VUNSET || (!doall && !(v->flags & VEXPORT))) - return NULL; - return v->text + v->name_len + 1; -} - - - -/* - * Generate a list of exported variables. This routine is used to construct - * the third argument to execve when executing a program. - */ - -char ** -environment(void) -{ - int nenv; - struct var **vpp; - struct var *vp; - char **env; - char **ep; - - nenv = 0; - for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { - for (vp = *vpp ; vp ; vp = vp->next) - if (vp->flags & VEXPORT) - nenv++; - } - ep = env = stalloc((nenv + 1) * sizeof *env); - for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { - for (vp = *vpp ; vp ; vp = vp->next) - if (vp->flags & VEXPORT) - *ep++ = vp->text; - } - *ep = NULL; - return env; -} - - -/* - * Called when a shell procedure is invoked to clear out nonexported - * variables. It is also necessary to reallocate variables of with - * VSTACK set since these are currently allocated on the stack. - */ - -#ifdef mkinit -void shprocvar(void); - -SHELLPROC { - shprocvar(); -} -#endif - -void -shprocvar(void) -{ - struct var **vpp; - struct var *vp, **prev; - - for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { - for (prev = vpp ; (vp = *prev) != NULL ; ) { - if ((vp->flags & VEXPORT) == 0) { - *prev = vp->next; - if ((vp->flags & VTEXTFIXED) == 0) - ckfree(vp->text); - if ((vp->flags & VSTRFIXED) == 0) - ckfree(vp); - } else { - if (vp->flags & VSTACK) { - vp->text = savestr(vp->text); - vp->flags &=~ VSTACK; - } - prev = &vp->next; - } - } - } - initvar(); -} - - - -/* - * Command to list all variables which are set. Currently this command - * is invoked from the set command when the set command is called without - * any variables. - */ - -void -print_quoted(const char *p) -{ - const char *q; - - if (strcspn(p, "|&;<>()$`\\\"' \t\n*?[]#~=%") == strlen(p)) { - out1fmt("%s", p); - return; - } - while (*p) { - if (*p == '\'') { - out1fmt("\\'"); - p++; - continue; - } - q = index(p, '\''); - if (!q) { - out1fmt("'%s'", p ); - return; - } - out1fmt("'%.*s'", (int)(q - p), p ); - p = q; - } -} - -static int -sort_var(const void *v_v1, const void *v_v2) -{ - const struct var * const *v1 = v_v1; - const struct var * const *v2 = v_v2; - - /* XXX Will anyone notice we include the '=' of the shorter name? */ - return strcmp((*v1)->text, (*v2)->text); -} - -/* - * POSIX requires that 'set' (but not export or readonly) output the - * variables in lexicographic order - by the locale's collating order (sigh). - * Maybe we could keep them in an ordered balanced binary tree - * instead of hashed lists. - * For now just roll 'em through qsort for printing... - */ - -int -showvars(const char *name, int flag, int show_value) -{ - struct var **vpp; - struct var *vp; - const char *p; - - static struct var **list; /* static in case we are interrupted */ - static int list_len; - int count = 0; - - if (!list) { - list_len = 32; - list = ckmalloc(list_len * sizeof *list); - } - - for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { - for (vp = *vpp ; vp ; vp = vp->next) { - if (flag && !(vp->flags & flag)) - continue; - if (vp->flags & VUNSET && !(show_value & 2)) - continue; - if (count >= list_len) { - list = ckrealloc(list, - (list_len << 1) * sizeof *list); - list_len <<= 1; - } - list[count++] = vp; - } - } - - qsort(list, count, sizeof *list, sort_var); - - for (vpp = list; count--; vpp++) { - vp = *vpp; - if (name) - out1fmt("%s ", name); - for (p = vp->text ; *p != '=' ; p++) - out1c(*p); - if (!(vp->flags & VUNSET) && show_value) { - out1fmt("="); - print_quoted(++p); - } - out1c('\n'); - } - return 0; -} - - - -/* - * The export and readonly commands. - */ - -int -exportcmd(int argc, char **argv) -{ - struct var *vp; - char *name; - const char *p; - int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; - int pflag; - - pflag = nextopt("p") == 'p' ? 3 : 0; - if (argc <= 1 || pflag) { - showvars( pflag ? argv[0] : 0, flag, pflag ); - return 0; - } - - while ((name = *argptr++) != NULL) { - if ((p = strchr(name, '=')) != NULL) { - p++; - } else { - vp = find_var(name, NULL, NULL); - if (vp != NULL) { - vp->flags |= flag; - continue; - } - } - setvar(name, p, flag); - } - return 0; -} - - -/* - * The "local" command. - */ - -int -localcmd(int argc, char **argv) -{ - char *name; - - if (! in_function()) - error("Not in a function"); - while ((name = *argptr++) != NULL) { - mklocal(name, 0); - } - return 0; -} - - -/* - * Make a variable a local variable. When a variable is made local, it's - * value and flags are saved in a localvar structure. The saved values - * will be restored when the shell function returns. We handle the name - * "-" as a special case. - */ - -void -mklocal(const char *name, int flags) -{ - struct localvar *lvp; - struct var **vpp; - struct var *vp; - - INTOFF; - lvp = ckmalloc(sizeof (struct localvar)); - if (name[0] == '-' && name[1] == '\0') { - char *p; - p = ckmalloc(sizeof_optlist); - lvp->text = memcpy(p, optlist, sizeof_optlist); - vp = NULL; - } else { - vp = find_var(name, &vpp, NULL); - if (vp == NULL) { - if (strchr(name, '=')) - setvareq(savestr(name), VSTRFIXED|flags); - else - setvar(name, NULL, VSTRFIXED|flags); - vp = *vpp; /* the new variable */ - lvp->text = NULL; - lvp->flags = VUNSET; - } else { - lvp->text = vp->text; - lvp->flags = vp->flags; - vp->flags |= VSTRFIXED|VTEXTFIXED; - if (name[vp->name_len] == '=') - setvareq(savestr(name), flags); - } - } - lvp->vp = vp; - lvp->next = localvars; - localvars = lvp; - INTON; -} - - -/* - * Called after a function returns. - */ - -void -poplocalvars(void) -{ - struct localvar *lvp; - struct var *vp; - - while ((lvp = localvars) != NULL) { - localvars = lvp->next; - vp = lvp->vp; - TRACE(("poplocalvar %s", vp ? vp->text : "-")); - if (vp == NULL) { /* $- saved */ - memcpy(optlist, lvp->text, sizeof_optlist); - ckfree(lvp->text); - } else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { - (void)unsetvar(vp->text, 0); - } else { - if (vp->func && (vp->flags & VNOFUNC) == 0) - (*vp->func)(lvp->text + vp->name_len + 1); - if ((vp->flags & VTEXTFIXED) == 0) - ckfree(vp->text); - vp->flags = lvp->flags; - vp->text = lvp->text; - } - ckfree(lvp); - } -} - - -int -setvarcmd(int argc, char **argv) -{ - if (argc <= 2) - return unsetcmd(argc, argv); - else if (argc == 3) - setvar(argv[1], argv[2], 0); - else - error("List assignment not implemented"); - return 0; -} - - -/* - * The unset builtin command. We unset the function before we unset the - * variable to allow a function to be unset when there is a readonly variable - * with the same name. - */ - -int -unsetcmd(int argc, char **argv) -{ - char **ap; - int i; - int flg_func = 0; - int flg_var = 0; - int ret = 0; - - while ((i = nextopt("evf")) != '\0') { - if (i == 'f') - flg_func = 1; - else - flg_var = i; - } - if (flg_func == 0 && flg_var == 0) - flg_var = 1; - - for (ap = argptr; *ap ; ap++) { - if (flg_func) - ret |= unsetfunc(*ap); - if (flg_var) - ret |= unsetvar(*ap, flg_var == 'e'); - } - return ret; -} - - -/* - * Unset the specified variable. - */ - -int -unsetvar(const char *s, int unexport) -{ - struct var **vpp; - struct var *vp; - - vp = find_var(s, &vpp, NULL); - if (vp == NULL) - return 1; - - if (vp->flags & VREADONLY) - return (1); - - INTOFF; - if (unexport) { - vp->flags &= ~VEXPORT; - } else { - if (vp->text[vp->name_len + 1] != '\0') - setvar(s, nullstr, 0); - vp->flags &= ~VEXPORT; - vp->flags |= VUNSET; - if ((vp->flags & VSTRFIXED) == 0) { - if ((vp->flags & VTEXTFIXED) == 0) - ckfree(vp->text); - *vpp = vp->next; - ckfree(vp); - } - } - INTON; - return 0; -} - - -/* - * Returns true if the two strings specify the same varable. The first - * variable name is terminated by '='; the second may be terminated by - * either '=' or '\0'. - */ - -STATIC int -strequal(const char *p, const char *q) -{ - while (*p == *q++) { - if (*p++ == '=') - return 1; - } - if (*p == '=' && *(q - 1) == '\0') - return 1; - return 0; -} - -/* - * Search for a variable. - * 'name' may be terminated by '=' or a NUL. - * vppp is set to the pointer to vp, or the list head if vp isn't found - * lenp is set to the number of charactets in 'name' - */ - -STATIC struct var * -find_var(const char *name, struct var ***vppp, int *lenp) -{ - unsigned int hashval; - int len; - struct var *vp, **vpp; - const char *p = name; - - hashval = 0; - while (*p && *p != '=') - hashval = 2 * hashval + (unsigned char)*p++; - len = p - name; - - if (lenp) - *lenp = len; - vpp = &vartab[hashval % VTABSIZE]; - if (vppp) - *vppp = vpp; - - for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) { - if (vp->name_len != len) - continue; - if (memcmp(vp->text, name, len) != 0) - continue; - if (vppp) - *vppp = vpp; - return vp; - } - return NULL; -} diff --git a/sh/var.h b/sh/var.h deleted file mode 100644 index b7b7db8146e0e77804bf01f65a9fe33576f5c369..0000000000000000000000000000000000000000 --- a/sh/var.h +++ /dev/null @@ -1,131 +0,0 @@ -/* $NetBSD: var.h,v 1.23 2004/10/02 12:16:53 dsl Exp $ */ - -/*- - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kenneth Almquist. - * - * 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. - * 3. 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. - * - * @(#)var.h 8.2 (Berkeley) 5/4/95 - */ - -/* - * Shell variables. - */ - -/* flags */ -#define VEXPORT 0x01 /* variable is exported */ -#define VREADONLY 0x02 /* variable cannot be modified */ -#define VSTRFIXED 0x04 /* variable struct is statically allocated */ -#define VTEXTFIXED 0x08 /* text is statically allocated */ -#define VSTACK 0x10 /* text is allocated on the stack */ -#define VUNSET 0x20 /* the variable is not set */ -#define VNOFUNC 0x40 /* don't call the callback function */ -#define VNOSET 0x80 /* do not set variable - just readonly test */ - - -struct var { - struct var *next; /* next entry in hash list */ - int flags; /* flags are defined above */ - char *text; /* name=value */ - int name_len; /* length of name */ - void (*func)(const char *); - /* function to be called when */ - /* the variable gets set/unset */ -}; - - -struct localvar { - struct localvar *next; /* next local variable in list */ - struct var *vp; /* the variable that was made local */ - int flags; /* saved flags */ - char *text; /* saved text */ -}; - - -struct localvar *localvars; - -#if ATTY -extern struct var vatty; -#endif -extern struct var vifs; -extern struct var vmpath; -extern struct var vpath; -extern struct var vps1; -extern struct var vps2; -extern struct var vps4; -#ifdef WITH_HISTORY -extern struct var vterm; -extern struct var vtermcap; -extern struct var vhistsize; -#endif - -/* - * The following macros access the values of the above variables. - * They have to skip over the name. They return the null string - * for unset variables. - */ - -#define ifsval() (vifs.text + 4) -#define ifsset() ((vifs.flags & VUNSET) == 0) -#define mpathval() (vmpath.text + 9) -#define pathval() (vpath.text + 5) -#define ps1val() (vps1.text + 4) -#define ps2val() (vps2.text + 4) -#define ps4val() (vps4.text + 4) -#define optindval() (voptind.text + 7) -#ifdef WITH_HISTORY -#define histsizeval() (vhistsize.text + 9) -#define termval() (vterm.text + 5) -#endif - -#if ATTY -#define attyset() ((vatty.flags & VUNSET) == 0) -#endif -#define mpathset() ((vmpath.flags & VUNSET) == 0) - -void initvar(void); -void setvar(const char *, const char *, int); -void setvareq(char *, int); -struct strlist; -void listsetvar(struct strlist *, int); -char *lookupvar(const char *); -char *bltinlookup(const char *, int); -char **environment(void); -void shprocvar(void); -int showvars(const char *, int, int); -int exportcmd(int, char **); -int localcmd(int, char **); -void mklocal(const char *, int); -void listmklocal(struct strlist *, int); -void poplocalvars(void); -int setvarcmd(int, char **); -int unsetcmd(int, char **); -int unsetvar(const char *, int); -int setvarsafe(const char *, const char *, int); -void print_quoted(const char *); diff --git a/toolbox/Android.mk b/toolbox/Android.mk deleted file mode 100644 index 5a8dc0b6d136a67e73ae57ee4aea68f2ed59e172..0000000000000000000000000000000000000000 --- a/toolbox/Android.mk +++ /dev/null @@ -1,91 +0,0 @@ -LOCAL_PATH:= $(call my-dir) -include $(CLEAR_VARS) - -TOOLS := \ - ls \ - mount \ - cat \ - ps \ - kill \ - ln \ - insmod \ - rmmod \ - lsmod \ - ifconfig \ - setconsole \ - rm \ - mkdir \ - rmdir \ - reboot \ - getevent \ - sendevent \ - date \ - wipe \ - sync \ - umount \ - start \ - stop \ - notify \ - cmp \ - dmesg \ - route \ - hd \ - dd \ - df \ - getprop \ - setprop \ - watchprops \ - log \ - sleep \ - renice \ - printenv \ - smd \ - chmod \ - chown \ - mkdosfs \ - netstat \ - ioctl \ - mv \ - schedtop \ - top \ - iftop \ - id \ - vmstat - -LOCAL_SRC_FILES:= \ - toolbox.c \ - $(patsubst %,%.c,$(TOOLS)) - -LOCAL_SHARED_LIBRARIES := libcutils libc - -LOCAL_MODULE:= toolbox - -# Including this will define $(intermediates). -# -include $(BUILD_EXECUTABLE) - -$(LOCAL_PATH)/toolbox.c: $(intermediates)/tools.h - -TOOLS_H := $(intermediates)/tools.h -$(TOOLS_H): PRIVATE_TOOLS := $(TOOLS) -$(TOOLS_H): PRIVATE_CUSTOM_TOOL = echo "/* file generated automatically */" > $@ ; for t in $(PRIVATE_TOOLS) ; do echo "TOOL($$t)" >> $@ ; done -$(TOOLS_H): $(LOCAL_PATH)/Android.mk -$(TOOLS_H): - $(transform-generated-source) - -# Make #!/system/bin/toolbox launchers for each tool. -# -SYMLINKS := $(addprefix $(TARGET_OUT)/bin/,$(TOOLS)) -$(SYMLINKS): TOOLBOX_BINARY := $(LOCAL_MODULE) -$(SYMLINKS): $(LOCAL_INSTALLED_MODULE) $(LOCAL_PATH)/Android.mk - @echo "Symlink: $@ -> $(TOOLBOX_BINARY)" - @mkdir -p $(dir $@) - @rm -rf $@ - $(hide) ln -sf $(TOOLBOX_BINARY) $@ - -ALL_DEFAULT_INSTALLED_MODULES += $(SYMLINKS) - -# We need this so that the installed files could be picked up based on the -# local module name -ALL_MODULES.$(LOCAL_MODULE).INSTALLED := \ - $(ALL_MODULES.$(LOCAL_MODULE).INSTALLED) $(SYMLINKS) diff --git a/toolbox/MODULE_LICENSE_BSD b/toolbox/MODULE_LICENSE_BSD deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/toolbox/NOTICE b/toolbox/NOTICE deleted file mode 100644 index 12f28b9e649bc21ecd0a76bae68f2a81618b2174..0000000000000000000000000000000000000000 --- a/toolbox/NOTICE +++ /dev/null @@ -1,131 +0,0 @@ - -Copyright (c) 2008, The Android Open Source Project -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * 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. - * Neither the name of The Android Open Source Project 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 COPYRIGHT HOLDERS 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 -COPYRIGHT OWNER 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) 1998 Robert Nordier -Copyright (c) 1989, 1993 - The Regents of the University of California. All rights reserved. - -This code is derived from software contributed to Berkeley by -Kevin Fall. -This code is derived from software contributed to Berkeley by -Keith Muller of the University of California, San Diego and Lance -Visser of Convex Computer Corporation. -This code is derived from software contributed to Berkeley by -Mike Muuss. - -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. -3. 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) 1989, 1993 - The Regents of the University of California. All rights reserved. - - This code is derived from software contributed to Berkeley by - Kevin Fall. - - 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. - 3. 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) 1991, 1993, 1994 - The Regents of the University of California. All rights reserved. - - This code is derived from software contributed to Berkeley by - Keith Muller of the University of California, San Diego and Lance - Visser of Convex Computer Corporation. - - 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. - 3. 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. - diff --git a/toolbox/alarm.c b/toolbox/alarm.c deleted file mode 100644 index 9bd58aa8d17f1e3d2bf35792745eda0c434cd25c..0000000000000000000000000000000000000000 --- a/toolbox/alarm.c +++ /dev/null @@ -1,190 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <asm/ioctl.h> -//#include <linux/rtc.h> -#include <linux/android_alarm.h> - -int alarm_main(int argc, char *argv[]) -{ - int c; - int res; - struct tm tm; - time_t t; - struct timespec ts; -// struct rtc_time rtc_time; - char strbuf[26]; - int afd; - int nfd; -// struct timeval timeout = { 0, 0 }; - int wait = 0; - fd_set rfds; - const char wake_lock_id[] = "alarm_test"; - int waitalarmmask = 0; - - int useutc = 0; - android_alarm_type_t alarmtype_low = ANDROID_ALARM_RTC_WAKEUP; - android_alarm_type_t alarmtype_high = ANDROID_ALARM_RTC_WAKEUP; - android_alarm_type_t alarmtype = 0; - - do { - //c = getopt(argc, argv, "uw:"); - c = getopt(argc, argv, "uwat:"); - if (c == EOF) - break; - switch (c) { - case 'u': - useutc = 1; - break; - case 't': - alarmtype_low = alarmtype_high = strtol(optarg, NULL, 0); - break; - case 'a': - alarmtype_low = ANDROID_ALARM_RTC_WAKEUP; - alarmtype_high = ANDROID_ALARM_TYPE_COUNT - 1; - break; - case 'w': - //timeout.tv_sec = strtol(optarg, NULL, 0); - wait = 1; - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - if(optind + 2 < argc) { - fprintf(stderr,"%s [-uwa] [-t type] [seconds]\n", argv[0]); - return 1; - } - - afd = open("/dev/alarm", O_RDWR); - if(afd < 0) { - fprintf(stderr, "Unable to open rtc: %s\n", strerror(errno)); - return 1; - } - - if(optind == argc) { - for(alarmtype = alarmtype_low; alarmtype <= alarmtype_high; alarmtype++) { - waitalarmmask |= 1U << alarmtype; - } -#if 0 - res = ioctl(fd, RTC_ALM_READ, &tm); - if(res < 0) { - fprintf(stderr, "Unable to read alarm: %s\n", strerror(errno)); - return 1; - } -#endif -#if 0 - t = timegm(&tm); - if(useutc) - gmtime_r(&t, &tm); - else - localtime_r(&t, &tm); -#endif -#if 0 - asctime_r(&tm, strbuf); - printf("%s", strbuf); -#endif - } - else if(optind + 1 == argc) { -#if 0 - res = ioctl(fd, RTC_RD_TIME, &tm); - if(res < 0) { - fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); - return 1; - } - asctime_r(&tm, strbuf); - printf("Now: %s", strbuf); - time(&tv.tv_sec); -#endif -#if 0 - time(&ts.tv_sec); - ts.tv_nsec = 0; - - //strptime(argv[optind], NULL, &tm); - //tv.tv_sec = mktime(&tm); - //tv.tv_usec = 0; -#endif - for(alarmtype = alarmtype_low; alarmtype <= alarmtype_high; alarmtype++) { - waitalarmmask |= 1U << alarmtype; - res = ioctl(afd, ANDROID_ALARM_GET_TIME(alarmtype), &ts); - if(res < 0) { - fprintf(stderr, "Unable to get current time: %s\n", strerror(errno)); - return 1; - } - ts.tv_sec += strtol(argv[optind], NULL, 0); - //strtotimeval(argv[optind], &tv); - gmtime_r(&ts.tv_sec, &tm); - printf("time %s -> %ld.%09ld\n", argv[optind], ts.tv_sec, ts.tv_nsec); - asctime_r(&tm, strbuf); - printf("Requested %s", strbuf); - - res = ioctl(afd, ANDROID_ALARM_SET(alarmtype), &ts); - if(res < 0) { - fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); - return 1; - } - } -#if 0 - res = ioctl(fd, RTC_ALM_SET, &tm); - if(res < 0) { - fprintf(stderr, "Unable to set alarm: %s\n", strerror(errno)); - return 1; - } - res = ioctl(fd, RTC_AIE_ON); - if(res < 0) { - fprintf(stderr, "Unable to enable alarm: %s\n", strerror(errno)); - return 1; - } -#endif - } - else { - fprintf(stderr,"%s [-u] [date]\n", argv[0]); - return 1; - } - - if(wait) { - while(waitalarmmask) { - printf("wait for alarm %x\n", waitalarmmask); - res = ioctl(afd, ANDROID_ALARM_WAIT); - if(res < 0) { - fprintf(stderr, "alarm wait failed\n"); - } - printf("got alarm %x\n", res); - waitalarmmask &= ~res; - nfd = open("/sys/android_power/acquire_full_wake_lock", O_RDWR); - write(nfd, wake_lock_id, sizeof(wake_lock_id) - 1); - close(nfd); - //sleep(5); - nfd = open("/sys/android_power/release_wake_lock", O_RDWR); - write(nfd, wake_lock_id, sizeof(wake_lock_id) - 1); - close(nfd); - } - printf("done\n"); - } -#if 0 - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - res = select(fd + 1, &rfds, NULL, NULL, &timeout); - if(res < 0) { - fprintf(stderr, "select failed: %s\n", strerror(errno)); - return 1; - } - if(res > 0) { - int event; - read(fd, &event, sizeof(event)); - fprintf(stderr, "got %x\n", event); - } - else { - fprintf(stderr, "timeout waiting for alarm\n"); - } -#endif - - close(afd); - - return 0; -} diff --git a/toolbox/cat.c b/toolbox/cat.c deleted file mode 100644 index 6ac31f87166cb0bd9f35c7b7ad229dce7b5dbce3..0000000000000000000000000000000000000000 --- a/toolbox/cat.c +++ /dev/null @@ -1,291 +0,0 @@ -/* $NetBSD: cat.c,v 1.43 2004/01/04 03:31:28 jschauma Exp $ */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Kevin Fall. - * - * 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. - * 3. 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. - */ - -#include <sys/param.h> -#include <sys/stat.h> - -#include <ctype.h> -#include <errno.h> -#include <fcntl.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#define CAT_BUFSIZ (4096) - -static int bflag, eflag, fflag, lflag, nflag, sflag, tflag, vflag; -static int rval; -static const char *filename; - -static void -cook_buf(FILE *fp) -{ - int ch, gobble, line, prev; - int stdout_err = 0; - - line = gobble = 0; - for (prev = '\n'; (ch = getc(fp)) != EOF; prev = ch) { - if (prev == '\n') { - if (ch == '\n') { - if (sflag) { - if (!gobble && putchar(ch) == EOF) - break; - gobble = 1; - continue; - } - if (nflag) { - if (!bflag) { - if (fprintf(stdout, - "%6d\t", ++line) < 0) { - stdout_err++; - break; - } - } else if (eflag) { - if (fprintf(stdout, - "%6s\t", "") < 0) { - stdout_err++; - break; - } - } - } - } else if (nflag) { - if (fprintf(stdout, "%6d\t", ++line) < 0) { - stdout_err++; - break; - } - } - } - gobble = 0; - if (ch == '\n') { - if (eflag) - if (putchar('$') == EOF) - break; - } else if (ch == '\t') { - if (tflag) { - if (putchar('^') == EOF || putchar('I') == EOF) - break; - continue; - } - } else if (vflag) { - if (!isascii(ch)) { - if (putchar('M') == EOF || putchar('-') == EOF) - break; - ch = (ch) & 0x7f; - } - if (iscntrl(ch)) { - if (putchar('^') == EOF || - putchar(ch == '\177' ? '?' : - ch | 0100) == EOF) - break; - continue; - } - } - if (putchar(ch) == EOF) - break; - } - if (stdout_err) { - perror(filename); - rval = 1; - } -} - -static void -cook_args(char **argv) -{ - FILE *fp; - - fp = stdin; - filename = "stdin"; - do { - if (*argv) { - if (!strcmp(*argv, "-")) - fp = stdin; - else if ((fp = fopen(*argv, - fflag ? "rf" : "r")) == NULL) { - perror("fopen"); - rval = 1; - ++argv; - continue; - } - filename = *argv++; - } - cook_buf(fp); - if (fp != stdin) - fclose(fp); - } while (*argv); -} - -static void -raw_cat(int rfd) -{ - static char *buf; - static char fb_buf[CAT_BUFSIZ]; - static size_t bsize; - - struct stat sbuf; - ssize_t nr, nw, off; - int wfd; - - wfd = fileno(stdout); - if (buf == NULL) { - if (fstat(wfd, &sbuf) == 0) { - bsize = sbuf.st_blksize > CAT_BUFSIZ ? - sbuf.st_blksize : CAT_BUFSIZ; - buf = malloc(bsize); - } - if (buf == NULL) { - buf = fb_buf; - bsize = CAT_BUFSIZ; - } - } - while ((nr = read(rfd, buf, bsize)) > 0) - for (off = 0; nr; nr -= nw, off += nw) - if ((nw = write(wfd, buf + off, (size_t)nr)) < 0) - { - perror("write"); - exit(EXIT_FAILURE); - } - if (nr < 0) { - fprintf(stderr,"%s: invalid length\n", filename); - rval = 1; - } -} - -static void -raw_args(char **argv) -{ - int fd; - - fd = fileno(stdin); - filename = "stdin"; - do { - if (*argv) { - if (!strcmp(*argv, "-")) - fd = fileno(stdin); - else if (fflag) { - struct stat st; - fd = open(*argv, O_RDONLY|O_NONBLOCK, 0); - if (fd < 0) - goto skip; - - if (fstat(fd, &st) == -1) { - close(fd); - goto skip; - } - if (!S_ISREG(st.st_mode)) { - close(fd); - errno = EINVAL; - goto skipnomsg; - } - } - else if ((fd = open(*argv, O_RDONLY, 0)) < 0) { -skip: - perror(*argv); -skipnomsg: - rval = 1; - ++argv; - continue; - } - filename = *argv++; - } - raw_cat(fd); - if (fd != fileno(stdin)) - close(fd); - } while (*argv); -} - -int -cat_main(int argc, char *argv[]) -{ - int ch; - struct flock stdout_lock; - - while ((ch = getopt(argc, argv, "beflnstv")) != -1) - switch (ch) { - case 'b': - bflag = nflag = 1; /* -b implies -n */ - break; - case 'e': - eflag = vflag = 1; /* -e implies -v */ - break; - case 'f': - fflag = 1; - break; - case 'l': - lflag = 1; - break; - case 'n': - nflag = 1; - break; - case 's': - sflag = 1; - break; - case 't': - tflag = vflag = 1; /* -t implies -v */ - break; - case 'v': - vflag = 1; - break; - default: - case '?': - fprintf(stderr, - "usage: cat [-beflnstv] [-] [file ...]\n"); - exit(EXIT_FAILURE); - } - argv += optind; - - if (lflag) { - stdout_lock.l_len = 0; - stdout_lock.l_start = 0; - stdout_lock.l_type = F_WRLCK; - stdout_lock.l_whence = SEEK_SET; - if (fcntl(STDOUT_FILENO, F_SETLKW, &stdout_lock) == -1) - { - perror("fcntl"); - exit(EXIT_FAILURE); - } - } - - if (bflag || eflag || nflag || sflag || tflag || vflag) - cook_args(argv); - else - raw_args(argv); - if (fclose(stdout)) - { - perror("fclose"); - exit(EXIT_FAILURE); - } - exit(rval); -} diff --git a/toolbox/chmod.c b/toolbox/chmod.c deleted file mode 100644 index 31a53bf7e7991138892ac13a80bdfe4a1641fda2..0000000000000000000000000000000000000000 --- a/toolbox/chmod.c +++ /dev/null @@ -1,40 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> - -#include <unistd.h> -#include <time.h> - -int chmod_main(int argc, char **argv) -{ - int i; - - if (argc < 3) { - fprintf(stderr, "Usage: chmod <MODE> <FILE>\n"); - return 10; - } - - int mode = 0; - const char* s = argv[1]; - while (*s) { - if (*s >= '0' && *s <= '7') { - mode = (mode<<3) | (*s-'0'); - } - else { - fprintf(stderr, "Bad mode\n"); - return 10; - } - s++; - } - for (i = 2; i < argc; i++) { - if (chmod(argv[i], mode) < 0) { - fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno)); - return 10; - } - } - return 0; -} - diff --git a/toolbox/chown.c b/toolbox/chown.c deleted file mode 100644 index 13617db681088a8e5b33aa3a7b6b16a627ac82c1..0000000000000000000000000000000000000000 --- a/toolbox/chown.c +++ /dev/null @@ -1,62 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> -#include <pwd.h> -#include <grp.h> - -#include <unistd.h> -#include <time.h> - -int chown_main(int argc, char **argv) -{ - int i; - - if (argc < 3) { - fprintf(stderr, "Usage: chown <USER>[.GROUP] <FILE1> [FILE2] ...\n"); - return 10; - } - - // Copy argv[1] to 'user' so we can truncate it at the period - // if a group id specified. - char user[32]; - char *group = NULL; - strncpy(user, argv[1], sizeof(user)); - if ((group = strchr(user, '.')) != NULL) { - *group++ = '\0'; - } - - // Lookup uid (and gid if specified) - struct passwd *pw; - struct group *grp = NULL; - uid_t uid; - gid_t gid = -1; // passing -1 to chown preserves current group - - pw = getpwnam(user); - if (pw == NULL) { - fprintf(stderr, "No such user '%s'\n", user); - return 10; - } - uid = pw->pw_uid; - - if (group != NULL) { - grp = getgrnam(group); - if (grp == NULL) { - fprintf(stderr, "No such group '%s'\n", group); - return 10; - } - gid = grp->gr_gid; - } - - for (i = 2; i < argc; i++) { - if (chown(argv[i], uid, gid) < 0) { - fprintf(stderr, "Unable to chmod %s: %s\n", argv[i], strerror(errno)); - return 10; - } - } - - return 0; -} - diff --git a/toolbox/cmp.c b/toolbox/cmp.c deleted file mode 100644 index 9bd2e19d8b2e0a0e090c420bbf068a20396d46b7..0000000000000000000000000000000000000000 --- a/toolbox/cmp.c +++ /dev/null @@ -1,90 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> - -int cmp_main(int argc, char *argv[]) -{ - int c; - int fd1, fd2; - char buf1[4096], buf2[4096]; - int res, res1, res2; - int rv = 0; - int i; - int filepos = 0; - - int show_byte = 0; - int show_all = 0; - int limit = 0; - - do { - c = getopt(argc, argv, "bln:"); - if (c == EOF) - break; - switch (c) { - case 'b': - show_byte = 1; - break; - case 'l': - show_all = 1; - break; - case 'n': - limit = atoi(optarg); - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if (optind + 2 != argc) { - fprintf(stderr, "Usage: %s [-b] [-l] [-n count] file1 file2\n", argv[0]); - exit(1); - } - - fd1 = open(argv[optind], O_RDONLY); - if(fd1 < 0) { - fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno)); - return 1; - } - - fd2 = open(argv[optind+1], O_RDONLY); - if(fd2 < 0) { - fprintf(stderr, "could not open %s, %s\n", argv[optind+1], strerror(errno)); - return 1; - } - - while(1) { - res1 = read(fd1, &buf1, sizeof(buf1)); - res2 = read(fd2, &buf2, sizeof(buf2)); - res = res1 < res2 ? res1 : res2; - if(res1 == 0 && res2 == 0) { - return rv; - } - for(i = 0; i < res; i++) { - if(buf1[i] != buf2[i]) { - printf("%s %s differ byte %d", argv[optind], argv[optind+1], filepos + i); - if(show_byte) - printf(" 0x%02x 0x%02x", buf1[i], buf2[i]); - printf("\n"); - if(!show_all) - return 1; - rv = 1; - } - if(limit) { - limit--; - if(limit == 0) - return rv; - } - } - if(res1 != res2 || res < 0) { - printf("%s on %s\n", res < 0 ? "Read error" : "EOF", res1 < res2 ? argv[optind] : argv[optind+1]); - return 1; - } - filepos += res; - } -} diff --git a/toolbox/date.c b/toolbox/date.c deleted file mode 100644 index 13b5210d73261ed8285973996e7a2cac869410ce..0000000000000000000000000000000000000000 --- a/toolbox/date.c +++ /dev/null @@ -1,132 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <linux/android_alarm.h> - -static void settime(char *s) { - struct tm tm; - int day = atoi(s); - int hour; - time_t t; - int fd; - struct timespec ts; - - while (*s && *s != '.') - s++; - - if (*s) - s++; - - hour = atoi(s); - - tm.tm_year = day / 10000 - 1900; - tm.tm_mon = (day % 10000) / 100 - 1; - tm.tm_mday = (day % 100); - tm.tm_hour = hour / 10000; - tm.tm_min = (hour % 10000) / 100; - tm.tm_sec = (hour % 100); - tm.tm_isdst = -1; - - t = mktime(&tm); - - fd = open("/dev/alarm", O_RDWR); - ts.tv_sec = t; - ts.tv_nsec = 0; - ioctl(fd, ANDROID_ALARM_SET_RTC, &ts); -} - -int date_main(int argc, char *argv[]) -{ - int c; - int res; - struct tm tm; - time_t t; - struct timeval tv; - struct timespec ts; - char strbuf[260]; - int fd; - - int useutc = 0; - - tzset(); - - do { - c = getopt(argc, argv, "us:"); - if (c == EOF) - break; - switch (c) { - case 'u': - useutc = 1; - break; - case 's': - settime(optarg); - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - if(optind + 2 < argc) { - fprintf(stderr,"%s [-u] [date]\n", argv[0]); - return 1; - } - - int hasfmt = argc == optind + 1 && argv[optind][0] == '+'; - if(optind == argc || hasfmt) { - char buf[2000]; - time(&t); - if (useutc) { - gmtime_r(&t, &tm); - strftime(strbuf, sizeof(strbuf), - (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S GMT %Y"), - &tm); - } else { - localtime_r(&t, &tm); - strftime(strbuf, sizeof(strbuf), - (hasfmt ? argv[optind] + 1 : "%a %b %e %H:%M:%S %Z %Y"), - &tm); - } - printf("%s\n", strbuf); - } - else if(optind + 1 == argc) { -#if 0 - struct tm *tmptr; - tmptr = getdate(argv[optind]); - if(tmptr == NULL) { - fprintf(stderr,"getdate_r failed\n"); - return 1; - } - tm = *tmptr; -#if 0 - if(getdate_r(argv[optind], &tm) < 0) { - fprintf(stderr,"getdate_r failed %s\n", strerror(errno)); - return 1; - } -#endif -#endif - //strptime(argv[optind], NULL, &tm); - //tv.tv_sec = mktime(&tm); - //tv.tv_usec = 0; - strtotimeval(argv[optind], &tv); - printf("time %s -> %d.%d\n", argv[optind], tv.tv_sec, tv.tv_usec); - fd = open("/dev/alarm", O_RDWR); - ts.tv_sec = tv.tv_sec; - ts.tv_nsec = tv.tv_usec * 1000; - res = ioctl(fd, ANDROID_ALARM_SET_RTC, &ts); - //res = settimeofday(&tv, NULL); - if(res < 0) { - fprintf(stderr,"settimeofday failed %s\n", strerror(errno)); - return 1; - } - } - else { - fprintf(stderr,"%s [-s 20070325.123456] [-u] [date]\n", argv[0]); - return 1; - } - - return 0; -} diff --git a/toolbox/dd.c b/toolbox/dd.c deleted file mode 100644 index c6af3ea43faec6097aa5ca0e9fb5c4b41dd03f85..0000000000000000000000000000000000000000 --- a/toolbox/dd.c +++ /dev/null @@ -1,1358 +0,0 @@ -/* $NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $ */ - -/*- - * Copyright (c) 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Keith Muller of the University of California, San Diego and Lance - * Visser of Convex Computer Corporation. - * - * 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. - * 3. 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. - */ - -#include <sys/cdefs.h> -#ifndef lint -__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\ - The Regents of the University of California. All rights reserved.\n"); -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)dd.c 8.5 (Berkeley) 4/2/94"; -#else -__RCSID("$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $"); -#endif -#endif /* not lint */ - -#include <sys/param.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/time.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "dd.h" - -#define NO_CONV - -//#include "extern.h" -void block(void); -void block_close(void); -void dd_out(int); -void def(void); -void def_close(void); -void jcl(char **); -void pos_in(void); -void pos_out(void); -void summary(void); -void summaryx(int); -void terminate(int); -void unblock(void); -void unblock_close(void); -ssize_t bwrite(int, const void *, size_t); - -extern IO in, out; -extern STAT st; -extern void (*cfunc)(void); -extern uint64_t cpy_cnt; -extern uint64_t cbsz; -extern u_int ddflags; -extern u_int files_cnt; -extern int progress; -extern const u_char *ctab; -extern const u_char a2e_32V[], a2e_POSIX[]; -extern const u_char e2a_32V[], e2a_POSIX[]; -extern const u_char a2ibm_32V[], a2ibm_POSIX[]; -extern u_char casetab[]; - - -#define MAX(a, b) ((a) > (b) ? (a) : (b)) - -static void dd_close(void); -static void dd_in(void); -static void getfdtype(IO *); -static int redup_clean_fd(int); -static void setup(void); - - -IO in, out; /* input/output state */ -STAT st; /* statistics */ -void (*cfunc)(void); /* conversion function */ -uint64_t cpy_cnt; /* # of blocks to copy */ -static off_t pending = 0; /* pending seek if sparse */ -u_int ddflags; /* conversion options */ -uint64_t cbsz; /* conversion block size */ -u_int files_cnt = 1; /* # of files to copy */ -int progress = 0; /* display sign of life */ -const u_char *ctab; /* conversion table */ -sigset_t infoset; /* a set blocking SIGINFO */ - -int -dd_main(int argc, char *argv[]) -{ - int ch; - - while ((ch = getopt(argc, argv, "")) != -1) { - switch (ch) { - default: - fprintf(stderr, "usage: dd [operand ...]\n"); - exit(1); - /* NOTREACHED */ - } - } - argc -= (optind - 1); - argv += (optind - 1); - - jcl(argv); - setup(); - -// (void)signal(SIGINFO, summaryx); - (void)signal(SIGINT, terminate); - (void)sigemptyset(&infoset); -// (void)sigaddset(&infoset, SIGINFO); - - (void)atexit(summary); - - while (files_cnt--) - dd_in(); - - dd_close(); - exit(0); - /* NOTREACHED */ -} - -static void -setup(void) -{ - - if (in.name == NULL) { - in.name = "stdin"; - in.fd = STDIN_FILENO; - } else { - in.fd = open(in.name, O_RDONLY, 0); - if (in.fd < 0) { - fprintf(stderr, "%s: cannot open for read: %s\n", - in.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - - /* Ensure in.fd is outside the stdio descriptor range */ - in.fd = redup_clean_fd(in.fd); - } - - getfdtype(&in); - - if (files_cnt > 1 && !(in.flags & ISTAPE)) { - fprintf(stderr, - "files is not supported for non-tape devices\n"); - exit(1); - /* NOTREACHED */ - } - - if (out.name == NULL) { - /* No way to check for read access here. */ - out.fd = STDOUT_FILENO; - out.name = "stdout"; - } else { -#define OFLAGS \ - (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC)) - out.fd = open(out.name, O_RDWR | OFLAGS /*, DEFFILEMODE */); - /* - * May not have read access, so try again with write only. - * Without read we may have a problem if output also does - * not support seeks. - */ - if (out.fd < 0) { - out.fd = open(out.name, O_WRONLY | OFLAGS /*, DEFFILEMODE */); - out.flags |= NOREAD; - } - if (out.fd < 0) { - fprintf(stderr, "%s: cannot open for write: %s\n", - out.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - - /* Ensure out.fd is outside the stdio descriptor range */ - out.fd = redup_clean_fd(out.fd); - } - - getfdtype(&out); - - /* - * Allocate space for the input and output buffers. If not doing - * record oriented I/O, only need a single buffer. - */ - if (!(ddflags & (C_BLOCK|C_UNBLOCK))) { - if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) { - exit(1); - /* NOTREACHED */ - } - out.db = in.db; - } else if ((in.db = - malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL || - (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) { - exit(1); - /* NOTREACHED */ - } - in.dbp = in.db; - out.dbp = out.db; - - /* Position the input/output streams. */ - if (in.offset) - pos_in(); - if (out.offset) - pos_out(); - - /* - * Truncate the output file; ignore errors because it fails on some - * kinds of output files, tapes, for example. - */ - if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK)) - (void)ftruncate(out.fd, (off_t)out.offset * out.dbsz); - - /* - * If converting case at the same time as another conversion, build a - * table that does both at once. If just converting case, use the - * built-in tables. - */ - if (ddflags & (C_LCASE|C_UCASE)) { -#ifdef NO_CONV - /* Should not get here, but just in case... */ - fprintf(stderr, "case conv and -DNO_CONV\n"); - exit(1); - /* NOTREACHED */ -#else /* NO_CONV */ - u_int cnt; - - if (ddflags & C_ASCII || ddflags & C_EBCDIC) { - if (ddflags & C_LCASE) { - for (cnt = 0; cnt < 0377; ++cnt) - casetab[cnt] = tolower(ctab[cnt]); - } else { - for (cnt = 0; cnt < 0377; ++cnt) - casetab[cnt] = toupper(ctab[cnt]); - } - } else { - if (ddflags & C_LCASE) { - for (cnt = 0; cnt < 0377; ++cnt) - casetab[cnt] = tolower(cnt); - } else { - for (cnt = 0; cnt < 0377; ++cnt) - casetab[cnt] = toupper(cnt); - } - } - - ctab = casetab; -#endif /* NO_CONV */ - } - - (void)gettimeofday(&st.start, NULL); /* Statistics timestamp. */ -} - -static void -getfdtype(IO *io) -{ -// struct mtget mt; - struct stat sb; - - if (fstat(io->fd, &sb)) { - fprintf(stderr, "%s: cannot fstat: %s\n", - io->name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - if (S_ISCHR(sb.st_mode)) - io->flags |= /*ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE; */ ISCHR; - else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE) - io->flags |= ISPIPE; /* XXX fixed in 4.4BSD */ -} - -/* - * Move the parameter file descriptor to a descriptor that is outside the - * stdio descriptor range, if necessary. This is required to avoid - * accidentally outputting completion or error messages into the - * output file that were intended for the tty. - */ -static int -redup_clean_fd(int fd) -{ - int newfd; - - if (fd != STDIN_FILENO && fd != STDOUT_FILENO && - fd != STDERR_FILENO) - /* File descriptor is ok, return immediately. */ - return fd; - - /* - * 3 is the first descriptor greater than STD*_FILENO. Any - * free descriptor valued 3 or above is acceptable... - */ - newfd = fcntl(fd, F_DUPFD, 3); - if (newfd < 0) { - fprintf(stderr, "dupfd IO: %s\n", strerror(errno)); - exit(1); - /* NOTREACHED */ - } - - close(fd); - - return newfd; -} - -static void -dd_in(void) -{ - int flags; - int64_t n; - - for (flags = ddflags;;) { - if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt) - return; - - /* - * Clear the buffer first if doing "sync" on input. - * If doing block operations use spaces. This will - * affect not only the C_NOERROR case, but also the - * last partial input block which should be padded - * with zero and not garbage. - */ - if (flags & C_SYNC) { - if (flags & (C_BLOCK|C_UNBLOCK)) - (void)memset(in.dbp, ' ', in.dbsz); - else - (void)memset(in.dbp, 0, in.dbsz); - } - - n = read(in.fd, in.dbp, in.dbsz); - if (n == 0) { - in.dbrcnt = 0; - return; - } - - /* Read error. */ - if (n < 0) { - - /* - * If noerror not specified, die. POSIX requires that - * the warning message be followed by an I/O display. - */ - fprintf(stderr, "%s: read error: %s\n", - in.name, strerror(errno)); - if (!(flags & C_NOERROR)) { - exit(1); - /* NOTREACHED */ - } - summary(); - - /* - * If it's not a tape drive or a pipe, seek past the - * error. If your OS doesn't do the right thing for - * raw disks this section should be modified to re-read - * in sector size chunks. - */ - if (!(in.flags & (ISPIPE|ISTAPE)) && - lseek(in.fd, (off_t)in.dbsz, SEEK_CUR)) - fprintf(stderr, "%s: seek error: %s\n", - in.name, strerror(errno)); - - /* If sync not specified, omit block and continue. */ - if (!(ddflags & C_SYNC)) - continue; - - /* Read errors count as full blocks. */ - in.dbcnt += in.dbrcnt = in.dbsz; - ++st.in_full; - - /* Handle full input blocks. */ - } else if (n == in.dbsz) { - in.dbcnt += in.dbrcnt = n; - ++st.in_full; - - /* Handle partial input blocks. */ - } else { - /* If sync, use the entire block. */ - if (ddflags & C_SYNC) - in.dbcnt += in.dbrcnt = in.dbsz; - else - in.dbcnt += in.dbrcnt = n; - ++st.in_part; - } - - /* - * POSIX states that if bs is set and no other conversions - * than noerror, notrunc or sync are specified, the block - * is output without buffering as it is read. - */ - if (ddflags & C_BS) { - out.dbcnt = in.dbcnt; - dd_out(1); - in.dbcnt = 0; - continue; - } - -/* if (ddflags & C_SWAB) { - if ((n = in.dbrcnt) & 1) { - ++st.swab; - --n; - } - swab(in.dbp, in.dbp, n); - } -*/ - in.dbp += in.dbrcnt; - (*cfunc)(); - } -} - -/* - * Cleanup any remaining I/O and flush output. If necesssary, output file - * is truncated. - */ -static void -dd_close(void) -{ - - if (cfunc == def) - def_close(); - else if (cfunc == block) - block_close(); - else if (cfunc == unblock) - unblock_close(); - if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) { - (void)memset(out.dbp, 0, out.dbsz - out.dbcnt); - out.dbcnt = out.dbsz; - } - /* If there are pending sparse blocks, make sure - * to write out the final block un-sparse - */ - if ((out.dbcnt == 0) && pending) { - memset(out.db, 0, out.dbsz); - out.dbcnt = out.dbsz; - out.dbp = out.db + out.dbcnt; - pending -= out.dbsz; - } - if (out.dbcnt) - dd_out(1); - - /* - * Reporting nfs write error may be defered until next - * write(2) or close(2) system call. So, we need to do an - * extra check. If an output is stdout, the file structure - * may be shared among with other processes and close(2) just - * decreases the reference count. - */ - if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) { - fprintf(stderr, "fsync stdout: %s\n", strerror(errno)); - exit(1); - /* NOTREACHED */ - } - if (close(out.fd) == -1) { - fprintf(stderr, "close: %s\n", strerror(errno)); - exit(1); - /* NOTREACHED */ - } -} - -void -dd_out(int force) -{ - static int warned; - int64_t cnt, n, nw; - u_char *outp; - - /* - * Write one or more blocks out. The common case is writing a full - * output block in a single write; increment the full block stats. - * Otherwise, we're into partial block writes. If a partial write, - * and it's a character device, just warn. If a tape device, quit. - * - * The partial writes represent two cases. 1: Where the input block - * was less than expected so the output block was less than expected. - * 2: Where the input block was the right size but we were forced to - * write the block in multiple chunks. The original versions of dd(1) - * never wrote a block in more than a single write, so the latter case - * never happened. - * - * One special case is if we're forced to do the write -- in that case - * we play games with the buffer size, and it's usually a partial write. - */ - outp = out.db; - for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) { - for (cnt = n;; cnt -= nw) { - - if (!force && ddflags & C_SPARSE) { - int sparse, i; - sparse = 1; /* Is buffer sparse? */ - for (i = 0; i < cnt; i++) - if (outp[i] != 0) { - sparse = 0; - break; - } - if (sparse) { - pending += cnt; - outp += cnt; - nw = 0; - break; - } - } - if (pending != 0) { - if (lseek(out.fd, pending, SEEK_CUR) == - -1) { - fprintf(stderr, - "%s: seek error creating " - "sparse file: %s\n", - out.name, strerror(errno)); - exit(1); - } - } - nw = bwrite(out.fd, outp, cnt); - if (nw <= 0) { - if (nw == 0) { - fprintf(stderr, "%s: end of device\n", - out.name); - exit(1); - /* NOTREACHED */ - } - if (errno != EINTR) { - fprintf(stderr, "%s: write error: %s\n", - out.name, strerror(errno)); - /* NOTREACHED */ - exit(1); - } - nw = 0; - } - if (pending) { - st.bytes += pending; - st.sparse += pending/out.dbsz; - st.out_full += pending/out.dbsz; - pending = 0; - } - outp += nw; - st.bytes += nw; - if (nw == n) { - if (n != out.dbsz) - ++st.out_part; - else - ++st.out_full; - break; - } - ++st.out_part; - if (nw == cnt) - break; - if (out.flags & ISCHR && !warned) { - warned = 1; - fprintf(stderr, "%s: short write on character " - "device\n", out.name); - } - if (out.flags & ISTAPE) { - fprintf(stderr, - "%s: short write on tape device", - out.name); - exit(1); - /* NOTREACHED */ - } - } - if ((out.dbcnt -= n) < out.dbsz) - break; - } - - /* Reassemble the output block. */ - if (out.dbcnt) - (void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt); - out.dbp = out.db + out.dbcnt; - - if (progress) - (void)write(STDERR_FILENO, ".", 1); -} - -/* - * A protected against SIGINFO write - */ -ssize_t -bwrite(int fd, const void *buf, size_t len) -{ - sigset_t oset; - ssize_t rv; - int oerrno; - - (void)sigprocmask(SIG_BLOCK, &infoset, &oset); - rv = write(fd, buf, len); - oerrno = errno; - (void)sigprocmask(SIG_SETMASK, &oset, NULL); - errno = oerrno; - return (rv); -} - -/* - * Position input/output data streams before starting the copy. Device type - * dependent. Seekable devices use lseek, and the rest position by reading. - * Seeking past the end of file can cause null blocks to be written to the - * output. - */ -void -pos_in(void) -{ - int bcnt, cnt, nr, warned; - - /* If not a pipe or tape device, try to seek on it. */ - if (!(in.flags & (ISPIPE|ISTAPE))) { - if (lseek(in.fd, - (off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) { - fprintf(stderr, "%s: seek error: %s", - in.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - return; - /* NOTREACHED */ - } - - /* - * Read the data. If a pipe, read until satisfy the number of bytes - * being skipped. No differentiation for reading complete and partial - * blocks for other devices. - */ - for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) { - if ((nr = read(in.fd, in.db, bcnt)) > 0) { - if (in.flags & ISPIPE) { - if (!(bcnt -= nr)) { - bcnt = in.dbsz; - --cnt; - } - } else - --cnt; - continue; - } - - if (nr == 0) { - if (files_cnt > 1) { - --files_cnt; - continue; - } - fprintf(stderr, "skip reached end of input\n"); - exit(1); - /* NOTREACHED */ - } - - /* - * Input error -- either EOF with no more files, or I/O error. - * If noerror not set die. POSIX requires that the warning - * message be followed by an I/O display. - */ - if (ddflags & C_NOERROR) { - if (!warned) { - - fprintf(stderr, "%s: error occurred\n", - in.name); - warned = 1; - summary(); - } - continue; - } - fprintf(stderr, "%s: read error: %s", in.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } -} - -void -pos_out(void) -{ -// struct mtop t_op; - int cnt, n; - - /* - * If not a tape, try seeking on the file. Seeking on a pipe is - * going to fail, but don't protect the user -- they shouldn't - * have specified the seek operand. - */ - if (!(out.flags & ISTAPE)) { - if (lseek(out.fd, - (off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1) { - fprintf(stderr, "%s: seek error: %s\n", - out.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - return; - } - - /* If no read access, try using mtio. */ - if (out.flags & NOREAD) { -/* t_op.mt_op = MTFSR; - t_op.mt_count = out.offset; - - if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)*/ - fprintf(stderr, "%s: cannot read", out.name); - exit(1); - /* NOTREACHED */ - return; - } - - /* Read it. */ - for (cnt = 0; cnt < out.offset; ++cnt) { - if ((n = read(out.fd, out.db, out.dbsz)) > 0) - continue; - - if (n < 0) { - fprintf(stderr, "%s: cannot position by reading: %s\n", - out.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - - /* - * If reach EOF, fill with NUL characters; first, back up over - * the EOF mark. Note, cnt has not yet been incremented, so - * the EOF read does not count as a seek'd block. - */ -/* t_op.mt_op = MTBSR; - t_op.mt_count = 1; - if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) */ { - fprintf(stderr, "%s: cannot position\n", out.name); - exit(1); - /* NOTREACHED */ - } - - while (cnt++ < out.offset) - if ((n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz) { - fprintf(stderr, "%s: cannot position " - "by writing: %s\n", - out.name, strerror(errno)); - exit(1); - /* NOTREACHED */ - } - break; - } -} - -/* - * def -- - * Copy input to output. Input is buffered until reaches obs, and then - * output until less than obs remains. Only a single buffer is used. - * Worst case buffer calculation is (ibs + obs - 1). - */ -void -def(void) -{ - uint64_t cnt; - u_char *inp; - const u_char *t; - - if ((t = ctab) != NULL) - for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp) - *inp = t[*inp]; - - /* Make the output buffer look right. */ - out.dbp = in.dbp; - out.dbcnt = in.dbcnt; - - if (in.dbcnt >= out.dbsz) { - /* If the output buffer is full, write it. */ - dd_out(0); - - /* - * Ddout copies the leftover output to the beginning of - * the buffer and resets the output buffer. Reset the - * input buffer to match it. - */ - in.dbp = out.dbp; - in.dbcnt = out.dbcnt; - } -} - -void -def_close(void) -{ - - /* Just update the count, everything is already in the buffer. */ - if (in.dbcnt) - out.dbcnt = in.dbcnt; -} - -#ifdef NO_CONV -/* Build a smaller version (i.e. for a miniroot) */ -/* These can not be called, but just in case... */ -static const char no_block[] = "unblock and -DNO_CONV?\n"; -void block(void) { fprintf(stderr, "%s", no_block + 2); exit(1); } -void block_close(void) { fprintf(stderr, "%s", no_block + 2); exit(1); } -void unblock(void) { fprintf(stderr, "%s", no_block); exit(1); } -void unblock_close(void) { fprintf(stderr, "%s", no_block); exit(1); } -#else /* NO_CONV */ - -/* - * Copy variable length newline terminated records with a max size cbsz - * bytes to output. Records less than cbs are padded with spaces. - * - * max in buffer: MAX(ibs, cbsz) - * max out buffer: obs + cbsz - */ -void -block(void) -{ - static int intrunc; - int ch = 0; /* pacify gcc */ - uint64_t cnt, maxlen; - u_char *inp, *outp; - const u_char *t; - - /* - * Record truncation can cross block boundaries. If currently in a - * truncation state, keep tossing characters until reach a newline. - * Start at the beginning of the buffer, as the input buffer is always - * left empty. - */ - if (intrunc) { - for (inp = in.db, cnt = in.dbrcnt; - cnt && *inp++ != '\n'; --cnt); - if (!cnt) { - in.dbcnt = 0; - in.dbp = in.db; - return; - } - intrunc = 0; - /* Adjust the input buffer numbers. */ - in.dbcnt = cnt - 1; - in.dbp = inp + cnt - 1; - } - - /* - * Copy records (max cbsz size chunks) into the output buffer. The - * translation is done as we copy into the output buffer. - */ - for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) { - maxlen = MIN(cbsz, in.dbcnt); - if ((t = ctab) != NULL) - for (cnt = 0; - cnt < maxlen && (ch = *inp++) != '\n'; ++cnt) - *outp++ = t[ch]; - else - for (cnt = 0; - cnt < maxlen && (ch = *inp++) != '\n'; ++cnt) - *outp++ = ch; - /* - * Check for short record without a newline. Reassemble the - * input block. - */ - if (ch != '\n' && in.dbcnt < cbsz) { - (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); - break; - } - - /* Adjust the input buffer numbers. */ - in.dbcnt -= cnt; - if (ch == '\n') - --in.dbcnt; - - /* Pad short records with spaces. */ - if (cnt < cbsz) - (void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt); - else { - /* - * If the next character wouldn't have ended the - * block, it's a truncation. - */ - if (!in.dbcnt || *inp != '\n') - ++st.trunc; - - /* Toss characters to a newline. */ - for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt); - if (!in.dbcnt) - intrunc = 1; - else - --in.dbcnt; - } - - /* Adjust output buffer numbers. */ - out.dbp += cbsz; - if ((out.dbcnt += cbsz) >= out.dbsz) - dd_out(0); - outp = out.dbp; - } - in.dbp = in.db + in.dbcnt; -} - -void -block_close(void) -{ - - /* - * Copy any remaining data into the output buffer and pad to a record. - * Don't worry about truncation or translation, the input buffer is - * always empty when truncating, and no characters have been added for - * translation. The bottom line is that anything left in the input - * buffer is a truncated record. Anything left in the output buffer - * just wasn't big enough. - */ - if (in.dbcnt) { - ++st.trunc; - (void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt); - (void)memset(out.dbp + in.dbcnt, - ctab ? ctab[' '] : ' ', cbsz - in.dbcnt); - out.dbcnt += cbsz; - } -} - -/* - * Convert fixed length (cbsz) records to variable length. Deletes any - * trailing blanks and appends a newline. - * - * max in buffer: MAX(ibs, cbsz) + cbsz - * max out buffer: obs + cbsz - */ -void -unblock(void) -{ - uint64_t cnt; - u_char *inp; - const u_char *t; - - /* Translation and case conversion. */ - if ((t = ctab) != NULL) - for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--) - *inp = t[*inp]; - /* - * Copy records (max cbsz size chunks) into the output buffer. The - * translation has to already be done or we might not recognize the - * spaces. - */ - for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) { - for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t); - if (t >= inp) { - cnt = t - inp + 1; - (void)memmove(out.dbp, inp, cnt); - out.dbp += cnt; - out.dbcnt += cnt; - } - ++out.dbcnt; - *out.dbp++ = '\n'; - if (out.dbcnt >= out.dbsz) - dd_out(0); - } - if (in.dbcnt) - (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); - in.dbp = in.db + in.dbcnt; -} - -void -unblock_close(void) -{ - uint64_t cnt; - u_char *t; - - if (in.dbcnt) { - warnx("%s: short input record", in.name); - for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t); - if (t >= in.db) { - cnt = t - in.db + 1; - (void)memmove(out.dbp, in.db, cnt); - out.dbp += cnt; - out.dbcnt += cnt; - } - ++out.dbcnt; - *out.dbp++ = '\n'; - } -} - -#endif /* NO_CONV */ - -#define tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000) - -void -summary(void) -{ - char buf[100]; - int64_t mS; - struct timeval tv; - - if (progress) - (void)write(STDERR_FILENO, "\n", 1); - - (void)gettimeofday(&tv, NULL); - mS = tv2mS(tv) - tv2mS(st.start); - if (mS == 0) - mS = 1; - /* Use snprintf(3) so that we don't reenter stdio(3). */ - (void)snprintf(buf, sizeof(buf), - "%llu+%llu records in\n%llu+%llu records out\n", - (unsigned long long)st.in_full, (unsigned long long)st.in_part, - (unsigned long long)st.out_full, (unsigned long long)st.out_part); - (void)write(STDERR_FILENO, buf, strlen(buf)); - if (st.swab) { - (void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n", - (unsigned long long)st.swab, - (st.swab == 1) ? "block" : "blocks"); - (void)write(STDERR_FILENO, buf, strlen(buf)); - } - if (st.trunc) { - (void)snprintf(buf, sizeof(buf), "%llu truncated %s\n", - (unsigned long long)st.trunc, - (st.trunc == 1) ? "block" : "blocks"); - (void)write(STDERR_FILENO, buf, strlen(buf)); - } - if (st.sparse) { - (void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n", - (unsigned long long)st.sparse, - (st.sparse == 1) ? "block" : "blocks"); - (void)write(STDERR_FILENO, buf, strlen(buf)); - } - (void)snprintf(buf, sizeof(buf), - "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n", - (unsigned long long) st.bytes, - (long) (mS / 1000), - (int) (mS % 1000), - (unsigned long long) (st.bytes * 1000LL / mS)); - (void)write(STDERR_FILENO, buf, strlen(buf)); -} - -void -terminate(int notused) -{ - - exit(0); - /* NOTREACHED */ -} - -static int c_arg(const void *, const void *); -#ifndef NO_CONV -static int c_conv(const void *, const void *); -#endif -static void f_bs(char *); -static void f_cbs(char *); -static void f_conv(char *); -static void f_count(char *); -static void f_files(char *); -static void f_ibs(char *); -static void f_if(char *); -static void f_obs(char *); -static void f_of(char *); -static void f_seek(char *); -static void f_skip(char *); -static void f_progress(char *); - -static const struct arg { - const char *name; - void (*f)(char *); - u_int set, noset; -} args[] = { - /* the array needs to be sorted by the first column so - bsearch() can be used to find commands quickly */ - { "bs", f_bs, C_BS, C_BS|C_IBS|C_OBS|C_OSYNC }, - { "cbs", f_cbs, C_CBS, C_CBS }, - { "conv", f_conv, 0, 0 }, - { "count", f_count, C_COUNT, C_COUNT }, - { "files", f_files, C_FILES, C_FILES }, - { "ibs", f_ibs, C_IBS, C_BS|C_IBS }, - { "if", f_if, C_IF, C_IF }, - { "obs", f_obs, C_OBS, C_BS|C_OBS }, - { "of", f_of, C_OF, C_OF }, - { "progress", f_progress, 0, 0 }, - { "seek", f_seek, C_SEEK, C_SEEK }, - { "skip", f_skip, C_SKIP, C_SKIP }, -}; - -/* - * args -- parse JCL syntax of dd. - */ -void -jcl(char **argv) -{ - struct arg *ap, tmp; - char *oper, *arg; - - in.dbsz = out.dbsz = 512; - - while ((oper = *++argv) != NULL) { - if ((arg = strchr(oper, '=')) == NULL) { - fprintf(stderr, "unknown operand %s\n", oper); - exit(1); - /* NOTREACHED */ - } - *arg++ = '\0'; - if (!*arg) { - fprintf(stderr, "no value specified for %s\n", oper); - exit(1); - /* NOTREACHED */ - } - tmp.name = oper; - if (!(ap = (struct arg *)bsearch(&tmp, args, - sizeof(args)/sizeof(struct arg), sizeof(struct arg), - c_arg))) { - fprintf(stderr, "unknown operand %s\n", tmp.name); - exit(1); - /* NOTREACHED */ - } - if (ddflags & ap->noset) { - fprintf(stderr, - "%s: illegal argument combination or already set\n", - tmp.name); - exit(1); - /* NOTREACHED */ - } - ddflags |= ap->set; - ap->f(arg); - } - - /* Final sanity checks. */ - - if (ddflags & C_BS) { - /* - * Bs is turned off by any conversion -- we assume the user - * just wanted to set both the input and output block sizes - * and didn't want the bs semantics, so we don't warn. - */ - if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE | - C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) { - ddflags &= ~C_BS; - ddflags |= C_IBS|C_OBS; - } - - /* Bs supersedes ibs and obs. */ - if (ddflags & C_BS && ddflags & (C_IBS|C_OBS)) - fprintf(stderr, "bs supersedes ibs and obs\n"); - } - - /* - * Ascii/ebcdic and cbs implies block/unblock. - * Block/unblock requires cbs and vice-versa. - */ - if (ddflags & (C_BLOCK|C_UNBLOCK)) { - if (!(ddflags & C_CBS)) { - fprintf(stderr, "record operations require cbs\n"); - exit(1); - /* NOTREACHED */ - } - cfunc = ddflags & C_BLOCK ? block : unblock; - } else if (ddflags & C_CBS) { - if (ddflags & (C_ASCII|C_EBCDIC)) { - if (ddflags & C_ASCII) { - ddflags |= C_UNBLOCK; - cfunc = unblock; - } else { - ddflags |= C_BLOCK; - cfunc = block; - } - } else { - fprintf(stderr, - "cbs meaningless if not doing record operations\n"); - exit(1); - /* NOTREACHED */ - } - } else - cfunc = def; - - /* Read, write and seek calls take off_t as arguments. - * - * The following check is not done because an off_t is a quad - * for current NetBSD implementations. - * - * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz) - * errx(1, "seek offsets cannot be larger than %d", INT_MAX); - */ -} - -static int -c_arg(const void *a, const void *b) -{ - - return (strcmp(((const struct arg *)a)->name, - ((const struct arg *)b)->name)); -} - -static long long strsuftoll(const char* name, const char* arg, int def, unsigned int max) -{ - long long result; - - if (sscanf(arg, "%lld", &result) == 0) - result = def; - return result; -} - -static void -f_bs(char *arg) -{ - - in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX); -} - -static void -f_cbs(char *arg) -{ - - cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX); -} - -static void -f_count(char *arg) -{ - - cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX); - if (!cpy_cnt) - terminate(0); -} - -static void -f_files(char *arg) -{ - - files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX); - if (!files_cnt) - terminate(0); -} - -static void -f_ibs(char *arg) -{ - - if (!(ddflags & C_BS)) - in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX); -} - -static void -f_if(char *arg) -{ - - in.name = arg; -} - -static void -f_obs(char *arg) -{ - - if (!(ddflags & C_BS)) - out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX); -} - -static void -f_of(char *arg) -{ - - out.name = arg; -} - -static void -f_seek(char *arg) -{ - - out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX); -} - -static void -f_skip(char *arg) -{ - - in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX); -} - -static void -f_progress(char *arg) -{ - - if (*arg != '0') - progress = 1; -} - -#ifdef NO_CONV -/* Build a small version (i.e. for a ramdisk root) */ -static void -f_conv(char *arg) -{ - - fprintf(stderr, "conv option disabled\n"); - exit(1); - /* NOTREACHED */ -} -#else /* NO_CONV */ - -static const struct conv { - const char *name; - u_int set, noset; - const u_char *ctab; -} clist[] = { - { "ascii", C_ASCII, C_EBCDIC, e2a_POSIX }, - { "block", C_BLOCK, C_UNBLOCK, NULL }, - { "ebcdic", C_EBCDIC, C_ASCII, a2e_POSIX }, - { "ibm", C_EBCDIC, C_ASCII, a2ibm_POSIX }, - { "lcase", C_LCASE, C_UCASE, NULL }, - { "noerror", C_NOERROR, 0, NULL }, - { "notrunc", C_NOTRUNC, 0, NULL }, - { "oldascii", C_ASCII, C_EBCDIC, e2a_32V }, - { "oldebcdic", C_EBCDIC, C_ASCII, a2e_32V }, - { "oldibm", C_EBCDIC, C_ASCII, a2ibm_32V }, - { "osync", C_OSYNC, C_BS, NULL }, - { "sparse", C_SPARSE, 0, NULL }, - { "swab", C_SWAB, 0, NULL }, - { "sync", C_SYNC, 0, NULL }, - { "ucase", C_UCASE, C_LCASE, NULL }, - { "unblock", C_UNBLOCK, C_BLOCK, NULL }, - /* If you add items to this table, be sure to add the - * conversions to the C_BS check in the jcl routine above. - */ -}; - -static void -f_conv(char *arg) -{ - struct conv *cp, tmp; - - while (arg != NULL) { - tmp.name = strsep(&arg, ","); - if (!(cp = (struct conv *)bsearch(&tmp, clist, - sizeof(clist)/sizeof(struct conv), sizeof(struct conv), - c_conv))) { - errx(EXIT_FAILURE, "unknown conversion %s", tmp.name); - /* NOTREACHED */ - } - if (ddflags & cp->noset) { - errx(EXIT_FAILURE, "%s: illegal conversion combination", tmp.name); - /* NOTREACHED */ - } - ddflags |= cp->set; - if (cp->ctab) - ctab = cp->ctab; - } -} - -static int -c_conv(const void *a, const void *b) -{ - - return (strcmp(((const struct conv *)a)->name, - ((const struct conv *)b)->name)); -} - -#endif /* NO_CONV */ - - diff --git a/toolbox/dd.h b/toolbox/dd.h deleted file mode 100644 index 794a464d260e4cb0461e4fc6c86612e56848aaf6..0000000000000000000000000000000000000000 --- a/toolbox/dd.h +++ /dev/null @@ -1,91 +0,0 @@ -/* $NetBSD: dd.h,v 1.12 2004/01/17 20:48:57 dbj Exp $ */ - -/*- - * Copyright (c) 1991, 1993, 1994 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Keith Muller of the University of California, San Diego and Lance - * Visser of Convex Computer Corporation. - * - * 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. - * 3. 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. - * - * @(#)dd.h 8.3 (Berkeley) 4/2/94 - */ - -/* Input/output stream state. */ -typedef struct { - u_char *db; /* buffer address */ - u_char *dbp; /* current buffer I/O address */ - uint64_t dbcnt; /* current buffer byte count */ - int64_t dbrcnt; /* last read byte count */ - uint64_t dbsz; /* buffer size */ - -#define ISCHR 0x01 /* character device (warn on short) */ -#define ISPIPE 0x02 /* pipe (not truncatable) */ -#define ISTAPE 0x04 /* tape (not seekable) */ -#define NOREAD 0x08 /* not readable */ - u_int flags; - - const char *name; /* name */ - int fd; /* file descriptor */ - uint64_t offset; /* # of blocks to skip */ -} IO; - -typedef struct { - uint64_t in_full; /* # of full input blocks */ - uint64_t in_part; /* # of partial input blocks */ - uint64_t out_full; /* # of full output blocks */ - uint64_t out_part; /* # of partial output blocks */ - uint64_t trunc; /* # of truncated records */ - uint64_t swab; /* # of odd-length swab blocks */ - uint64_t sparse; /* # of sparse output blocks */ - uint64_t bytes; /* # of bytes written */ - struct timeval start; /* start time of dd */ -} STAT; - -/* Flags (in ddflags). */ -#define C_ASCII 0x00001 -#define C_BLOCK 0x00002 -#define C_BS 0x00004 -#define C_CBS 0x00008 -#define C_COUNT 0x00010 -#define C_EBCDIC 0x00020 -#define C_FILES 0x00040 -#define C_IBS 0x00080 -#define C_IF 0x00100 -#define C_LCASE 0x00200 -#define C_NOERROR 0x00400 -#define C_NOTRUNC 0x00800 -#define C_OBS 0x01000 -#define C_OF 0x02000 -#define C_SEEK 0x04000 -#define C_SKIP 0x08000 -#define C_SWAB 0x10000 -#define C_SYNC 0x20000 -#define C_UCASE 0x40000 -#define C_UNBLOCK 0x80000 -#define C_OSYNC 0x100000 -#define C_SPARSE 0x200000 diff --git a/toolbox/df.c b/toolbox/df.c deleted file mode 100644 index 90476bdc8f25f105cebc19bfefe6ba8ebc1a5438..0000000000000000000000000000000000000000 --- a/toolbox/df.c +++ /dev/null @@ -1,63 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <sys/statfs.h> - -static int ok = EXIT_SUCCESS; - -static void df(char *s, int always) { - struct statfs st; - - if (statfs(s, &st) < 0) { - fprintf(stderr, "%s: %s\n", s, strerror(errno)); - ok = EXIT_FAILURE; - } else { - if (st.f_blocks == 0 && !always) - return; - - printf("%s: %lldK total, %lldK used, %lldK available (block size %d)\n", - s, - ((long long)st.f_blocks * (long long)st.f_bsize) / 1024, - ((long long)(st.f_blocks - (long long)st.f_bfree) * st.f_bsize) / 1024, - ((long long)st.f_bfree * (long long)st.f_bsize) / 1024, - (int) st.f_bsize); - } -} - -int df_main(int argc, char *argv[]) { - if (argc == 1) { - char s[2000]; - FILE *f = fopen("/proc/mounts", "r"); - - while (fgets(s, 2000, f)) { - char *c, *e = s; - - for (c = s; *c; c++) { - if (*c == ' ') { - e = c + 1; - break; - } - } - - for (c = e; *c; c++) { - if (*c == ' ') { - *c = '\0'; - break; - } - } - - df(e, 0); - } - - fclose(f); - } else { - int i; - - for (i = 1; i < argc; i++) { - df(argv[i], 1); - } - } - - exit(ok); -} diff --git a/toolbox/dmesg.c b/toolbox/dmesg.c deleted file mode 100644 index e57f6077f17511c6beec815c64233f788c14493d..0000000000000000000000000000000000000000 --- a/toolbox/dmesg.c +++ /dev/null @@ -1,43 +0,0 @@ -#include <stdlib.h> -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <sys/klog.h> -#include <string.h> - -#define KLOG_BUF_SHIFT 17 /* CONFIG_LOG_BUF_SHIFT from our kernel */ -#define KLOG_BUF_LEN (1 << KLOG_BUF_SHIFT) - -int dmesg_main(int argc, char **argv) -{ - char buffer[KLOG_BUF_LEN + 1]; - char *p = buffer; - ssize_t ret; - int n, op; - - if((argc == 2) && (!strcmp(argv[1],"-c"))) { - op = KLOG_READ_CLEAR; - } else { - op = KLOG_READ_ALL; - } - - n = klogctl(op, buffer, KLOG_BUF_LEN); - if (n < 0) { - perror("klogctl"); - return EXIT_FAILURE; - } - buffer[n] = '\0'; - - while((ret = write(STDOUT_FILENO, p, n))) { - if (ret == -1) { - if (errno == EINTR) - continue; - perror("write"); - return EXIT_FAILURE; - } - p += ret; - n -= ret; - } - - return 0; -} diff --git a/toolbox/exists.c b/toolbox/exists.c deleted file mode 100644 index e3486689f930f889c239e59ca49ce9a60fab75ae..0000000000000000000000000000000000000000 --- a/toolbox/exists.c +++ /dev/null @@ -1,16 +0,0 @@ -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -int exists_main(int argc, char *argv[]) -{ - struct stat s; - - if(argc < 2) return 1; - - if(stat(argv[1], &s)) { - return 1; - } else { - return 0; - } -} diff --git a/toolbox/getevent.c b/toolbox/getevent.c deleted file mode 100644 index 14372cba13e72a6b714c8eac8672496b2032151d..0000000000000000000000000000000000000000 --- a/toolbox/getevent.c +++ /dev/null @@ -1,427 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <dirent.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/inotify.h> -#include <sys/limits.h> -#include <sys/poll.h> -#include <linux/input.h> // this does not compile -#include <errno.h> - -static struct pollfd *ufds; -static char **device_names; -static int nfds; - -enum { - PRINT_DEVICE_ERRORS = 1U << 0, - PRINT_DEVICE = 1U << 1, - PRINT_DEVICE_NAME = 1U << 2, - PRINT_DEVICE_INFO = 1U << 3, - PRINT_VERSION = 1U << 4, - PRINT_POSSIBLE_EVENTS = 1U << 5, -}; - -static int print_possible_events(int fd) -{ - uint8_t *bits = NULL; - ssize_t bits_size = 0; - int i, j, k; - int res, res2; - - printf(" events:\n"); - for(i = 0; i <= EV_MAX; i++) { - int count = 0; - while(1) { - res = ioctl(fd, EVIOCGBIT(i, bits_size), bits); - if(res < bits_size) - break; - bits_size = res + 16; - bits = realloc(bits, bits_size * 2); - if(bits == NULL) { - fprintf(stderr, "failed to allocate buffer of size %d\n", bits_size); - return 1; - } - } - switch(i) { - case EV_KEY: - res2 = ioctl(fd, EVIOCGKEY(res), bits + bits_size); - break; - case EV_LED: - res2 = ioctl(fd, EVIOCGLED(res), bits + bits_size); - break; - case EV_SND: - res2 = ioctl(fd, EVIOCGSND(res), bits + bits_size); - break; - case EV_SW: - res2 = ioctl(fd, EVIOCGSW(bits_size), bits + bits_size); - break; - default: - res2 = 0; - } - for(j = 0; j < res; j++) { - for(k = 0; k < 8; k++) - if(bits[j] & 1 << k) { - char down; - if(j < res2 && (bits[j + bits_size] & 1 << k)) - down = '*'; - else - down = ' '; - if(count == 0) - printf(" type %04x:", i); - else if((count & 0x7) == 0 || i == EV_ABS) - printf("\n "); - printf(" %04x%c", j * 8 + k, down); - if(i == EV_ABS) { - struct input_absinfo abs; - if(ioctl(fd, EVIOCGABS(j * 8 + k), &abs) == 0) { - printf(" value %d, min %d, max %d, fuzz %d flat %d", abs.value, abs.minimum, abs.maximum, abs.fuzz, abs.flat); - } - } - count++; - } - } - if(count) - printf("\n"); - } - free(bits); - return 0; -} - -static int open_device(const char *device, int print_flags) -{ - int version; - int fd; - struct pollfd *new_ufds; - char **new_device_names; - char name[80]; - char location[80]; - char idstr[80]; - struct input_id id; - - fd = open(device, O_RDWR); - if(fd < 0) { - if(print_flags & PRINT_DEVICE_ERRORS) - fprintf(stderr, "could not open %s, %s\n", device, strerror(errno)); - return -1; - } - - if(ioctl(fd, EVIOCGVERSION, &version)) { - if(print_flags & PRINT_DEVICE_ERRORS) - fprintf(stderr, "could not get driver version for %s, %s\n", device, strerror(errno)); - return -1; - } - if(ioctl(fd, EVIOCGID, &id)) { - if(print_flags & PRINT_DEVICE_ERRORS) - fprintf(stderr, "could not get driver id for %s, %s\n", device, strerror(errno)); - return -1; - } - name[sizeof(name) - 1] = '\0'; - location[sizeof(location) - 1] = '\0'; - idstr[sizeof(idstr) - 1] = '\0'; - if(ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) { - //fprintf(stderr, "could not get device name for %s, %s\n", device, strerror(errno)); - name[0] = '\0'; - } - if(ioctl(fd, EVIOCGPHYS(sizeof(location) - 1), &location) < 1) { - //fprintf(stderr, "could not get location for %s, %s\n", device, strerror(errno)); - location[0] = '\0'; - } - if(ioctl(fd, EVIOCGUNIQ(sizeof(idstr) - 1), &idstr) < 1) { - //fprintf(stderr, "could not get idstring for %s, %s\n", device, strerror(errno)); - idstr[0] = '\0'; - } - - new_ufds = realloc(ufds, sizeof(ufds[0]) * (nfds + 1)); - if(new_ufds == NULL) { - fprintf(stderr, "out of memory\n"); - return -1; - } - ufds = new_ufds; - new_device_names = realloc(device_names, sizeof(device_names[0]) * (nfds + 1)); - if(new_device_names == NULL) { - fprintf(stderr, "out of memory\n"); - return -1; - } - device_names = new_device_names; - - if(print_flags & PRINT_DEVICE) - printf("add device %d: %s\n", nfds, device); - if(print_flags & PRINT_DEVICE_INFO) - printf(" bus: %04x\n" - " vendor %04x\n" - " product %04x\n" - " version %04x\n", - id.bustype, id.vendor, id.product, id.version); - if(print_flags & PRINT_DEVICE_NAME) - printf(" name: \"%s\"\n", name); - if(print_flags & PRINT_DEVICE_INFO) - printf(" location: \"%s\"\n" - " id: \"%s\"\n", location, idstr); - if(print_flags & PRINT_VERSION) - printf(" version: %d.%d.%d\n", - version >> 16, (version >> 8) & 0xff, version & 0xff); - - if(print_flags & PRINT_POSSIBLE_EVENTS) { - print_possible_events(fd); - } - - ufds[nfds].fd = fd; - ufds[nfds].events = POLLIN; - device_names[nfds] = strdup(device); - nfds++; - - return 0; -} - -int close_device(const char *device, int print_flags) -{ - int i; - for(i = 1; i < nfds; i++) { - if(strcmp(device_names[i], device) == 0) { - int count = nfds - i - 1; - if(print_flags & PRINT_DEVICE) - printf("remove device %d: %s\n", i, device); - free(device_names[i]); - memmove(device_names + i, device_names + i + 1, sizeof(device_names[0]) * count); - memmove(ufds + i, ufds + i + 1, sizeof(ufds[0]) * count); - nfds--; - return 0; - } - } - if(print_flags & PRINT_DEVICE_ERRORS) - fprintf(stderr, "remote device: %s not found\n", device); - return -1; -} - -static int read_notify(const char *dirname, int nfd, int print_flags) -{ - int res; - char devname[PATH_MAX]; - char *filename; - char event_buf[512]; - int event_size; - int event_pos = 0; - struct inotify_event *event; - - res = read(nfd, event_buf, sizeof(event_buf)); - if(res < (int)sizeof(*event)) { - if(errno == EINTR) - return 0; - fprintf(stderr, "could not get event, %s\n", strerror(errno)); - return 1; - } - //printf("got %d bytes of event information\n", res); - - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - - while(res >= (int)sizeof(*event)) { - event = (struct inotify_event *)(event_buf + event_pos); - //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); - if(event->len) { - strcpy(filename, event->name); - if(event->mask & IN_CREATE) { - open_device(devname, print_flags); - } - else { - close_device(devname, print_flags); - } - } - event_size = sizeof(*event) + event->len; - res -= event_size; - event_pos += event_size; - } - return 0; -} - -static int scan_dir(const char *dirname, int print_flags) -{ - char devname[PATH_MAX]; - char *filename; - DIR *dir; - struct dirent *de; - dir = opendir(dirname); - if(dir == NULL) - return -1; - strcpy(devname, dirname); - filename = devname + strlen(devname); - *filename++ = '/'; - while((de = readdir(dir))) { - if(de->d_name[0] == '.' && - (de->d_name[1] == '\0' || - (de->d_name[1] == '.' && de->d_name[2] == '\0'))) - continue; - strcpy(filename, de->d_name); - open_device(devname, print_flags); - } - closedir(dir); - return 0; -} - -static void usage(int argc, char *argv[]) -{ - fprintf(stderr, "Usage: %s [-t] [-n] [-s switchmask] [-S] [-v [mask]] [-q] [-c count] [-r] [device]\n", argv[0]); -} - -int getevent_main(int argc, char *argv[]) -{ - int c; - int i; - int res; - int pollres; - int get_time = 0; - int print_device = 0; - char *newline = "\n"; - uint16_t get_switch = 0; - struct input_event event; - int version; - int print_flags = PRINT_DEVICE_ERRORS | PRINT_DEVICE | PRINT_DEVICE_NAME; - int print_flags_set = 0; - int dont_block = -1; - int event_count = 0; - int sync_rate = 0; - int64_t last_sync_time = 0; - const char *device = NULL; - const char *device_path = "/dev/input"; - - opterr = 0; - do { - c = getopt(argc, argv, "tns:Sv::qc:rh"); - if (c == EOF) - break; - switch (c) { - case 't': - get_time = 1; - break; - case 'n': - newline = ""; - break; - case 's': - get_switch = strtoul(optarg, NULL, 0); - if(dont_block == -1) - dont_block = 1; - break; - case 'S': - get_switch = ~0; - if(dont_block == -1) - dont_block = 1; - break; - case 'v': - if(optarg) - print_flags = strtoul(optarg, NULL, 0); - else - print_flags |= PRINT_DEVICE | PRINT_DEVICE_NAME | PRINT_DEVICE_INFO | PRINT_VERSION; - print_flags_set = 1; - break; - case 'q': - print_flags = 0; - print_flags_set = 1; - break; - case 'c': - event_count = atoi(optarg); - dont_block = 0; - break; - case 'r': - sync_rate = 1; - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - case 'h': - usage(argc, argv); - exit(1); - } - } while (1); - if(dont_block == -1) - dont_block = 0; - - if (optind + 1 == argc) { - device = argv[optind]; - optind++; - } - if (optind != argc) { - usage(argc, argv); - exit(1); - } - nfds = 1; - ufds = calloc(1, sizeof(ufds[0])); - ufds[0].fd = inotify_init(); - ufds[0].events = POLLIN; - if(device) { - if(!print_flags_set) - print_flags = PRINT_DEVICE_ERRORS; - res = open_device(device, print_flags); - if(res < 0) { - return 1; - } - } - else { - print_device = 1; - res = inotify_add_watch(ufds[0].fd, device_path, IN_DELETE | IN_CREATE); - if(res < 0) { - fprintf(stderr, "could not add watch for %s, %s\n", device_path, strerror(errno)); - return 1; - } - res = scan_dir(device_path, print_flags); - if(res < 0) { - fprintf(stderr, "scan dir failed for %s\n", device_path); - return 1; - } - } - - if(get_switch) { - for(i = 1; i < nfds; i++) { - uint16_t sw; - res = ioctl(ufds[i].fd, EVIOCGSW(1), &sw); - if(res < 0) { - fprintf(stderr, "could not get switch state, %s\n", strerror(errno)); - return 1; - } - sw &= get_switch; - printf("%04x%s", sw, newline); - } - } - - if(dont_block) - return 0; - - while(1) { - pollres = poll(ufds, nfds, -1); - //printf("poll %d, returned %d\n", nfds, pollres); - if(ufds[0].revents & POLLIN) { - read_notify(device_path, ufds[0].fd, print_flags); - } - for(i = 1; i < nfds; i++) { - if(ufds[i].revents) { - if(ufds[i].revents & POLLIN) { - res = read(ufds[i].fd, &event, sizeof(event)); - if(res < (int)sizeof(event)) { - fprintf(stderr, "could not get event\n"); - return 1; - } - if(get_time) { - printf("%ld-%ld: ", event.time.tv_sec, event.time.tv_usec); - } - if(print_device) - printf("%s: ", device_names[i]); - printf("%04x %04x %08x", event.type, event.code, event.value); - if(sync_rate && event.type == 0 && event.code == 0) { - int64_t now = event.time.tv_sec * 1000000LL + event.time.tv_usec; - if(last_sync_time) - printf(" rate %lld", 1000000LL / (now - last_sync_time)); - last_sync_time = now; - } - printf("%s", newline); - if(event_count && --event_count == 0) - return 0; - } - } - } - } - - return 0; -} diff --git a/toolbox/getprop.c b/toolbox/getprop.c deleted file mode 100644 index fc80a4debb06e21dc5b2cc0532b02e9bab843a50..0000000000000000000000000000000000000000 --- a/toolbox/getprop.c +++ /dev/null @@ -1,34 +0,0 @@ -#include <stdio.h> - -#include <cutils/properties.h> - -#include <sys/system_properties.h> - -static void proplist(const char *key, const char *name, - void *user __attribute__((unused))) -{ - printf("[%s]: [%s]\n", key, name); -} - -int __system_property_wait(prop_info *pi); - -int getprop_main(int argc, char *argv[]) -{ - int n = 0; - - if (argc == 1) { - (void)property_list(proplist, NULL); - } else { - char value[PROPERTY_VALUE_MAX]; - char *default_value; - if(argc > 2) { - default_value = argv[2]; - } else { - default_value = ""; - } - - property_get(argv[1], value, default_value); - printf("%s\n", value); - } - return 0; -} diff --git a/toolbox/hd.c b/toolbox/hd.c deleted file mode 100644 index 1f7d179341338aa3424e8893bf6762329ad810e3..0000000000000000000000000000000000000000 --- a/toolbox/hd.c +++ /dev/null @@ -1,95 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <errno.h> - -int hd_main(int argc, char *argv[]) -{ - int c; - int fd; - unsigned char buf[4096]; - int res; - int read_len; - int rv = 0; - int i; - int filepos = 0; - int sum; - int lsum; - - int base = -1; - int count = 0; - int repeat = 0; - - do { - c = getopt(argc, argv, "b:c:r:"); - if (c == EOF) - break; - switch (c) { - case 'b': - base = strtol(optarg, NULL, 0); - break; - case 'c': - count = strtol(optarg, NULL, 0); - break; - case 'r': - repeat = strtol(optarg, NULL, 0); - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if (optind + 1 != argc) { - fprintf(stderr, "Usage: %s [-b base] [-c count] [-r delay] file\n", argv[0]); - exit(1); - } - - fd = open(argv[optind], O_RDONLY); - if(fd < 0) { - fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno)); - return 1; - } - - do { - if(base >= 0) { - lseek(fd, base, SEEK_SET); - filepos = base; - } - sum = 0; - lsum = 0; - while(1) { - read_len = sizeof(buf); - if(count > 0 && base + count - filepos < read_len) - read_len = base + count - filepos; - res = read(fd, &buf, read_len); - for(i = 0; i < res; i++) { - if((i & 15) == 0) { - printf("%08x: ", filepos + i); - } - lsum += buf[i]; - sum += buf[i]; - printf("%02x ", buf[i]); - if(((i & 15) == 15) || (i == res - 1)) { - printf("s %x\n", lsum); - lsum = 0; - } - } - if(res <= 0) { - printf("Read error on %s, offset %d len %d, %s\n", argv[optind], filepos, read_len, strerror(errno)); - return 1; - } - filepos += res; - if(filepos == base + count) - break; - } - printf("sum %x\n", sum); - if(repeat) - sleep(repeat); - } while(repeat); - return 0; -} diff --git a/toolbox/id.c b/toolbox/id.c deleted file mode 100644 index bb03cad2ae655b9dac24661019e226454c1b895f..0000000000000000000000000000000000000000 --- a/toolbox/id.c +++ /dev/null @@ -1,51 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <pwd.h> -#include <grp.h> - -static void print_uid(uid_t uid) -{ - struct passwd *pw = getpwuid(uid); - - if (pw) { - printf("%d(%s)", uid, pw->pw_name); - } else { - printf("%d",uid); - } -} - -static void print_gid(gid_t gid) -{ - struct group *gr = getgrgid(gid); - if (gr) { - printf("%d(%s)", gid, gr->gr_name); - } else { - printf("%d",gid); - } -} - -int id_main(int argc, char **argv) -{ - gid_t list[64]; - int n, max; - - max = getgroups(64, list); - if (max < 0) max = 0; - - printf("uid="); - print_uid(getuid()); - printf(" gid="); - print_gid(getgid()); - if (max) { - printf(" groups="); - print_gid(list[0]); - for(n = 1; n < max; n++) { - printf(","); - print_gid(list[n]); - } - } - printf("\n"); - return 0; -} diff --git a/toolbox/ifconfig.c b/toolbox/ifconfig.c deleted file mode 100644 index e83cd8bada5af1eb44a4467435dd459ada7ebf86..0000000000000000000000000000000000000000 --- a/toolbox/ifconfig.c +++ /dev/null @@ -1,139 +0,0 @@ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <string.h> -#include <ctype.h> - -#include <sys/socket.h> -#include <netinet/in.h> -#include <linux/if.h> -#include <linux/sockios.h> -#include <arpa/inet.h> - -static void die(const char *s) -{ - fprintf(stderr,"error: %s (%s)\n", s, strerror(errno)); - exit(-1); -} - -static void setflags(int s, struct ifreq *ifr, int set, int clr) -{ - if(ioctl(s, SIOCGIFFLAGS, ifr) < 0) die("SIOCGIFFLAGS"); - ifr->ifr_flags = (ifr->ifr_flags & (~clr)) | set; - if(ioctl(s, SIOCSIFFLAGS, ifr) < 0) die("SIOCSIFFLAGS"); -} - -static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) -{ - sin->sin_family = AF_INET; - sin->sin_port = 0; - sin->sin_addr.s_addr = inet_addr(addr); -} - -static void setnetmask(int s, struct ifreq *ifr, const char *addr) -{ - init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_netmask, addr); - if(ioctl(s, SIOCSIFNETMASK, ifr) < 0) die("SIOCSIFNETMASK"); -} - -static void setaddr(int s, struct ifreq *ifr, const char *addr) -{ - init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_addr, addr); - if(ioctl(s, SIOCSIFADDR, ifr) < 0) die("SIOCSIFADDR"); -} - -int ifconfig_main(int argc, char *argv[]) -{ - struct ifreq ifr; - int s; - unsigned int addr, mask, flags; - char astring[20]; - char mstring[20]; - char *updown, *brdcst, *loopbk, *ppp, *running, *multi; - - argc--; - argv++; - - if(argc == 0) return 0; - - memset(&ifr, 0, sizeof(struct ifreq)); - strncpy(ifr.ifr_name, argv[0], IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = 0; - argc--, argv++; - - if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - die("cannot open control socket\n"); - } - - if (argc == 0) { - if (ioctl(s, SIOCGIFADDR, &ifr) < 0) { - perror(ifr.ifr_name); - return -1; - } else - addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; - - if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0) { - perror(ifr.ifr_name); - return -1; - } else - mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr; - - if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) { - perror(ifr.ifr_name); - return -1; - } else - flags = ifr.ifr_flags; - - sprintf(astring, "%d.%d.%d.%d", - addr & 0xff, - ((addr >> 8) & 0xff), - ((addr >> 16) & 0xff), - ((addr >> 24) & 0xff)); - sprintf(mstring, "%d.%d.%d.%d", - mask & 0xff, - ((mask >> 8) & 0xff), - ((mask >> 16) & 0xff), - ((mask >> 24) & 0xff)); - printf("%s: ip %s mask %s flags [", ifr.ifr_name, - astring, - mstring - ); - - updown = (flags & IFF_UP) ? "up" : "down"; - brdcst = (flags & IFF_BROADCAST) ? " broadcast" : ""; - loopbk = (flags & IFF_LOOPBACK) ? " loopback" : ""; - ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : ""; - running = (flags & IFF_RUNNING) ? " running" : ""; - multi = (flags & IFF_MULTICAST) ? " multicast" : ""; - printf("%s%s%s%s%s%s]\n", updown, brdcst, loopbk, ppp, running, multi); - - - -/* char *updown, *brdcst, *loopbk, *ppp, *running, *multi; */ - - return 0; - } - - while(argc > 0){ - if(!strcmp(argv[0], "up")) { - setflags(s, &ifr, IFF_UP, 0); - } else if(!strcmp(argv[0], "down")) { - setflags(s, &ifr, 0, IFF_UP); - } else if(!strcmp(argv[0], "netmask")) { - argc--, argv++; - if (0 == argc) { - errno = EINVAL; - die("expecting an IP address for parameter \"netmask\""); - } - setnetmask(s, &ifr, argv[0]); - } else if(isdigit(argv[0][0])){ - setaddr(s, &ifr, argv[0]); - } - argc--, argv++; - } - - return 0; -} diff --git a/toolbox/iftop.c b/toolbox/iftop.c deleted file mode 100644 index 800c0f0e528ce8b6a3fd69542655663523e7ae10..0000000000000000000000000000000000000000 --- a/toolbox/iftop.c +++ /dev/null @@ -1,278 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/socket.h> -#include <net/if.h> - -#define PROC_NET_DEV "/proc/net/dev" - -#define MAX_IF 8 /* max interfaces we can handle */ - -#ifndef PAGE_SIZE -# define PAGE_SIZE 4096 -#endif - -#define _STR(s) #s -#define STR(s) _STR(s) - -struct if_stats { - char name[IFNAMSIZ]; - - unsigned int mtu; - - unsigned int rx_bytes; - unsigned int rx_packets; - unsigned int rx_errors; - unsigned int rx_dropped; - - unsigned int tx_bytes; - unsigned int tx_packets; - unsigned int tx_errors; - unsigned int tx_dropped; -}; - -static int get_mtu(const char *if_name) -{ - struct ifreq ifr; - int s, ret; - - s = socket(AF_INET, SOCK_DGRAM, 0); - if (s < 0) { - perror("socket"); - exit(EXIT_FAILURE); - } - - memset(&ifr, 0, sizeof(struct ifreq)); - ifr.ifr_addr.sa_family = AF_INET; - strcpy(ifr.ifr_name, if_name); - - ret = ioctl(s, SIOCGIFMTU, &ifr); - if (ret < 0) { - perror("ioctl"); - exit(EXIT_FAILURE); - } - - ret = close(s); - if (ret < 0) { - perror("close"); - exit(EXIT_FAILURE); - } - - return ifr.ifr_mtu; -} - -static int get_interfaces(struct if_stats *ifs) -{ - char buf[PAGE_SIZE]; - char *p; - int ret, nr, fd; - - fd = open(PROC_NET_DEV, O_RDONLY); - if (fd < 0) { - perror("open"); - exit(EXIT_FAILURE); - } - - ret = read(fd, buf, sizeof(buf) - 1); - if (ret < 0) { - perror("read"); - exit(EXIT_FAILURE); - } else if (!ret) { - fprintf(stderr, "reading " PROC_NET_DEV " returned premature EOF\n"); - exit(EXIT_FAILURE); - } - buf[ret] = '\0'; - - /* skip down to the third line */ - p = strchr(buf, '\n'); - if (!p) { - fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n"); - exit(EXIT_FAILURE); - } - p = strchr(p + 1, '\n'); - if (!p) { - fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n"); - exit(EXIT_FAILURE); - } - p += 1; - - /* - * Key: - * if: (Rx) bytes packets errs drop fifo frame compressed multicast \ - * (Tx) bytes packets errs drop fifo colls carrier compressed - */ - for (nr = 0; nr < MAX_IF; nr++) { - char *c; - - ret = sscanf(p, "%" STR(IFNAMSIZ) "s", ifs->name); - if (ret != 1) { - fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n"); - exit(EXIT_FAILURE); - } - - /* - * This works around a bug in the proc file where large interface names - * or Rx byte counts eat the delimiter, breaking sscanf. - */ - c = strchr(ifs->name, ':'); - if (c) - *c = '\0'; - - p = strchr(p, ':') + 1; - - ret = sscanf(p, "%u %u %u %u %*u %*u %*u %*u %u %u %u %u %*u %*u " - "%*u %*u\n", &ifs->rx_bytes, &ifs->rx_packets, - &ifs->rx_errors, &ifs->rx_dropped, &ifs->tx_bytes, - &ifs->tx_packets, &ifs->tx_errors, &ifs->tx_dropped); - if (ret != 8) { - fprintf(stderr, "parsing " PROC_NET_DEV " failed unexpectedly\n"); - exit(EXIT_FAILURE); - } - - ifs->mtu = get_mtu(ifs->name); - - p = strchr(p, '\n') + 1; - if (*p == '\0') { - nr++; - break; - } - - ifs++; - } - - ret = close(fd); - if (ret) { - perror("close"); - exit(EXIT_FAILURE); - } - - return nr; -} - -static void print_header(void) -{ - printf(" Rx Tx\n"); - printf("%-8s %-5s %-10s %-8s %-5s %-5s %-10s %-8s %-5s %-5s\n", - "name", "MTU", "bytes", "packets", "errs", "drpd", "bytes", - "packets", "errs", "drpd"); -} - -static int print_interfaces(struct if_stats *old, struct if_stats *new, int nr) -{ - int i = 0; - - while (nr--) { - if (old->rx_packets || old->tx_packets) { - printf("%-8s %-5u %-10u %-8u %-5u %-5u %-10u %-8u %-5u %-5u\n", - new->name, new->mtu, - new->rx_bytes - old->rx_bytes, - new->rx_packets - old->rx_packets, - new->rx_errors - old->rx_errors, - new->rx_dropped - old->rx_dropped, - new->tx_bytes - old->tx_bytes, - new->tx_packets - old->tx_packets, - new->tx_errors - old->tx_errors, - new->tx_dropped - old->tx_dropped); - i++; - } - old++; - new++; - } - - return i; -} - -static void usage(const char *cmd) -{ - fprintf(stderr, "usage: %s [ -r repeats] [ -d delay ]\n", cmd); -} - -int iftop_main(int argc, char *argv[]) -{ - struct if_stats ifs[2][MAX_IF]; - int count = 0, header_interval = 22, delay = 1, i; - unsigned int toggle = 0; - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-d")) { - if (i >= argc - 1) { - fprintf(stderr, "Option -d requires an argument.\n"); - exit(EXIT_FAILURE); - } - delay = atoi(argv[i++]); - if (!delay) - delay = 1; - continue; - } - if (!strcmp(argv[i], "-r")) { - if (i >= argc - 1) { - fprintf(stderr, "Option -r requires an argument.\n"); - exit(EXIT_FAILURE); - } - header_interval = atoi(argv[i++]); - if (header_interval < MAX_IF) - header_interval = MAX_IF; - continue; - } - if (!strcmp(argv[i], "-h")) { - usage(argv[0]); - exit(EXIT_SUCCESS); - } - usage(argv[0]); - exit(EXIT_FAILURE); - } - - get_interfaces(ifs[!toggle]); - if (header_interval) - print_header(); - while (1) { - int nr; - - sleep(delay); - nr = get_interfaces(ifs[toggle]); - if (header_interval && count + nr > header_interval) { - print_header(); - count = 0; - } - count += print_interfaces(ifs[!toggle], ifs[toggle], nr); - toggle = !toggle; - } - - return 0; -} diff --git a/toolbox/insmod.c b/toolbox/insmod.c deleted file mode 100644 index 44b98474b3e4f8373f0306560b935884a44276a0..0000000000000000000000000000000000000000 --- a/toolbox/insmod.c +++ /dev/null @@ -1,98 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <malloc.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -extern int init_module(void *, unsigned long, const char *); - -static void *read_file(const char *filename, ssize_t *_size) -{ - int ret, fd; - struct stat sb; - ssize_t size; - void *buffer = NULL; - - /* open the file */ - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - - /* find out how big it is */ - if (fstat(fd, &sb) < 0) - goto bail; - size = sb.st_size; - - /* allocate memory for it to be read into */ - buffer = malloc(size); - if (!buffer) - goto bail; - - /* slurp it into our buffer */ - ret = read(fd, buffer, size); - if (ret != size) - goto bail; - - /* let the caller know how big it is */ - *_size = size; - -bail: - close(fd); - return buffer; -} - -#define min(x,y) ((x) < (y) ? (x) : (y)) -int insmod_main(int argc, char **argv) -{ - void *file; - ssize_t size = 0; - char opts[1024]; - int ret; - - /* make sure we've got an argument */ - if (argc < 2) { - fprintf(stderr, "usage: insmod <module.o>\n"); - return -1; - } - - /* read the file into memory */ - file = read_file(argv[1], &size); - if (!file) { - fprintf(stderr, "insmod: can't open '%s'\n", argv[1]); - return -1; - } - - opts[0] = '\0'; - if (argc > 2) { - int i, len; - char *end = opts + sizeof(opts) - 1; - char *ptr = opts; - - for (i = 2; (i < argc) && (ptr < end); i++) { - len = min(strlen(argv[i]), end - ptr); - memcpy(ptr, argv[i], len); - ptr += len; - *ptr++ = ' '; - *ptr++ = '\0'; - } - *(ptr - 1) = '\0'; - } - - /* pass it to the kernel */ - ret = init_module(file, size, opts); - if (ret != 0) { - fprintf(stderr, - "insmod: init_module '%s' failed (%s)\n", - argv[1], strerror(errno)); - } - - /* free the file buffer */ - free(file); - - return ret; -} - diff --git a/toolbox/ioctl.c b/toolbox/ioctl.c deleted file mode 100644 index e28f2a4668af9146f99234423a6022ec3a44848f..0000000000000000000000000000000000000000 --- a/toolbox/ioctl.c +++ /dev/null @@ -1,125 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <linux/kd.h> -#include <linux/vt.h> -#include <errno.h> -#include <pthread.h> - -int ioctl_main(int argc, char *argv[]) -{ - int c; - int fd; - int res; - - int read_only = 0; - int length = -1; - int arg_size = 4; - int direct_arg = 0; - uint32_t ioctl_nr; - void *ioctl_args; - uint8_t *ioctl_argp; - uint8_t *ioctl_argp_save; - int rem; - - do { - c = getopt(argc, argv, "rdl:a:h"); - if (c == EOF) - break; - switch (c) { - case 'r': - read_only = 1; - break; - case 'd': - direct_arg = 1; - break; - case 'l': - length = strtol(optarg, NULL, 0); - break; - case 'a': - arg_size = strtol(optarg, NULL, 0); - break; - case 'h': - fprintf(stderr, "%s [-l <length>] [-a <argsize>] [-rdh] <device> <ioctlnr>\n" - " -l <lenght> Length of io buffer\n" - " -a <argsize> Size of each argument (1-8)\n" - " -r Open device in read only mode\n" - " -d Direct argument (no iobuffer)\n" - " -h Print help\n", argv[0]); - return -1; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if(optind + 2 > argc) { - fprintf(stderr, "%s: too few arguments\n", argv[0]); - exit(1); - } - - fd = open(argv[optind], O_RDWR | O_SYNC); - if (fd < 0) { - fprintf(stderr, "cannot open %s\n", argv[optind]); - return 1; - } - optind++; - - ioctl_nr = strtol(argv[optind], NULL, 0); - optind++; - - if(direct_arg) { - arg_size = 4; - length = 4; - } - - if(length < 0) { - length = (argc - optind) * arg_size; - } - if(length) { - ioctl_args = calloc(1, length); - - ioctl_argp_save = ioctl_argp = ioctl_args; - rem = length; - while(optind < argc) { - uint64_t tmp = strtoull(argv[optind], NULL, 0); - if(rem < arg_size) { - fprintf(stderr, "%s: too many arguments\n", argv[0]); - exit(1); - } - memcpy(ioctl_argp, &tmp, arg_size); - ioctl_argp += arg_size; - rem -= arg_size; - optind++; - } - } - printf("sending ioctl 0x%x", ioctl_nr); - rem = length; - while(rem--) { - printf(" 0x%02x", *ioctl_argp_save++); - } - printf("\n"); - - if(direct_arg) - res = ioctl(fd, ioctl_nr, *(uint32_t*)ioctl_args); - else if(length) - res = ioctl(fd, ioctl_nr, ioctl_args); - else - res = ioctl(fd, ioctl_nr, 0); - if (res < 0) { - fprintf(stderr, "ioctl 0x%x failed, %d\n", ioctl_nr, res); - return 1; - } - if(length) { - printf("return buf:"); - ioctl_argp = ioctl_args; - rem = length; - while(rem--) { - printf(" %02x", *ioctl_argp++); - } - printf("\n"); - } - return 0; -} diff --git a/toolbox/kill.c b/toolbox/kill.c deleted file mode 100644 index 4d0e47999c261c7e15289973c8d48c802fdbd006..0000000000000000000000000000000000000000 --- a/toolbox/kill.c +++ /dev/null @@ -1,35 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <errno.h> - -#include <sys/types.h> -#include <signal.h> - -int kill_main(int argc, char **argv) -{ - int sig = SIGTERM; - int result = 0; - - argc--; - argv++; - - if(argc >= 2 && argv[0][0] == '-'){ - sig = atoi(argv[0] + 1); - argc--; - argv++; - } - - while(argc > 0){ - int pid = atoi(argv[0]); - int err = kill(pid, sig); - if (err < 0) { - result = err; - fprintf(stderr, "could not kill pid %d: %s\n", pid, strerror(errno)); - } - - argc--; - argv++; - } - - return result; -} diff --git a/toolbox/ln.c b/toolbox/ln.c deleted file mode 100644 index dcd5e3aea2e9c4065d81d57999d380626f5dc437..0000000000000000000000000000000000000000 --- a/toolbox/ln.c +++ /dev/null @@ -1,34 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -static int usage() -{ - fprintf(stderr,"ln [-s] <target> <name>\n"); - return -1; -} - -int ln_main(int argc, char *argv[]) -{ - int symbolic = 0; - int ret; - if(argc < 2) return usage(); - - if(!strcmp(argv[1],"-s")) { - symbolic = 1; - argc--; - argv++; - } - - if(argc < 3) return usage(); - - if(symbolic) { - ret = symlink(argv[1], argv[2]); - } else { - ret = link(argv[1], argv[2]); - } - if(ret < 0) - fprintf(stderr, "link failed %s\n", strerror(errno)); - return ret; -} diff --git a/toolbox/log.c b/toolbox/log.c deleted file mode 100644 index f30e6a7827ce3ce5e78bb22fd2649b2c872f77dc..0000000000000000000000000000000000000000 --- a/toolbox/log.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <cutils/logd.h> -#include <ctype.h> -#include <sys/socket.h> -#include <sys/types.h> -#include <stdlib.h> -#include <cutils/sockets.h> -#include <unistd.h> - -/* - * Note: also accepts 0-9 priorities - * returns ANDROID_LOG_UNKNOWN if the character is unrecognized - */ -static android_LogPriority filterCharToPri (char c) -{ - android_LogPriority pri; - - c = tolower(c); - - if (c >= '0' && c <= '9') { - if (c >= ('0'+ANDROID_LOG_SILENT)) { - pri = ANDROID_LOG_VERBOSE; - } else { - pri = (android_LogPriority)(c - '0'); - } - } else if (c == 'v') { - pri = ANDROID_LOG_VERBOSE; - } else if (c == 'd') { - pri = ANDROID_LOG_DEBUG; - } else if (c == 'i') { - pri = ANDROID_LOG_INFO; - } else if (c == 'w') { - pri = ANDROID_LOG_WARN; - } else if (c == 'e') { - pri = ANDROID_LOG_ERROR; - } else if (c == 'f') { - pri = ANDROID_LOG_FATAL; - } else if (c == 's') { - pri = ANDROID_LOG_SILENT; - } else if (c == '*') { - pri = ANDROID_LOG_DEFAULT; - } else { - pri = ANDROID_LOG_UNKNOWN; - } - - return pri; -} - -static int usage(const char *s) -{ - fprintf(stderr, "USAGE: %s [-p priorityChar] [-t tag] message\n", s); - - fprintf(stderr, "\tpriorityChar should be one of:\n" - "\t\tv,d,i,w,e\n"); - exit(-1); -} - - -int log_main(int argc, char *argv[]) -{ - android_LogPriority priority; - const char *tag = "log"; - char buffer[4096]; - int i; - - priority = ANDROID_LOG_INFO; - - for (;;) { - int ret; - - ret = getopt(argc, argv, "t:p:h"); - - if (ret < 0) { - break; - } - - switch(ret) { - case 't': - tag = optarg; - break; - - case 'p': - priority = filterCharToPri(optarg[0]); - if (priority == ANDROID_LOG_UNKNOWN) { - usage(argv[0]); - } - break; - - case 'h': - usage(argv[0]); - break; - } - } - - if (optind == argc) { - usage(argv[0]); - } - - buffer[0] = '\0'; - - for (i = optind ; i < argc ; i++) { - strncat(buffer, argv[i], sizeof(buffer)-1); - strncat(buffer, " ", sizeof(buffer)-1); - } - - if(buffer[0] == 0) { - usage(argv[0]); - } - - __android_log_print(priority, tag, "%s", buffer); - - return 0; -} - diff --git a/toolbox/ls.c b/toolbox/ls.c deleted file mode 100644 index f609df21cb80d783834db3a2dc3b14179dd70495..0000000000000000000000000000000000000000 --- a/toolbox/ls.c +++ /dev/null @@ -1,285 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <dirent.h> -#include <errno.h> - -#include <sys/stat.h> -#include <unistd.h> -#include <time.h> - -#include <pwd.h> -#include <grp.h> - -#include <linux/kdev_t.h> - -// bits for flags argument -#define LIST_LONG (1 << 0) -#define LIST_ALL (1 << 1) -#define LIST_RECURSIVE (1 << 2) - -// fwd -static int listpath(const char *name, int flags); - -static char mode2kind(unsigned mode) -{ - switch(mode & S_IFMT){ - case S_IFSOCK: return 's'; - case S_IFLNK: return 'l'; - case S_IFREG: return '-'; - case S_IFDIR: return 'd'; - case S_IFBLK: return 'b'; - case S_IFCHR: return 'c'; - case S_IFIFO: return 'p'; - default: return '?'; - } -} - -static void mode2str(unsigned mode, char *out) -{ - *out++ = mode2kind(mode); - - *out++ = (mode & 0400) ? 'r' : '-'; - *out++ = (mode & 0200) ? 'w' : '-'; - if(mode & 04000) { - *out++ = (mode & 0100) ? 's' : 'S'; - } else { - *out++ = (mode & 0100) ? 'x' : '-'; - } - *out++ = (mode & 040) ? 'r' : '-'; - *out++ = (mode & 020) ? 'w' : '-'; - if(mode & 02000) { - *out++ = (mode & 010) ? 's' : 'S'; - } else { - *out++ = (mode & 010) ? 'x' : '-'; - } - *out++ = (mode & 04) ? 'r' : '-'; - *out++ = (mode & 02) ? 'w' : '-'; - if(mode & 01000) { - *out++ = (mode & 01) ? 't' : 'T'; - } else { - *out++ = (mode & 01) ? 'x' : '-'; - } - *out = 0; -} - -static void user2str(unsigned uid, char *out) -{ - struct passwd *pw = getpwuid(uid); - if(pw) { - strcpy(out, pw->pw_name); - } else { - sprintf(out, "%d", uid); - } -} - -static void group2str(unsigned gid, char *out) -{ - struct group *gr = getgrgid(gid); - if(gr) { - strcpy(out, gr->gr_name); - } else { - sprintf(out, "%d", gid); - } -} - -static int listfile(const char *path, int flags) -{ - struct stat s; - char date[32]; - char mode[16]; - char user[16]; - char group[16]; - const char *name; - - /* name is anything after the final '/', or the whole path if none*/ - name = strrchr(path, '/'); - if(name == 0) { - name = path; - } else { - name++; - } - - if(lstat(path, &s) < 0) { - return -1; - } - - mode2str(s.st_mode, mode); - user2str(s.st_uid, user); - group2str(s.st_gid, group); - - strftime(date, 32, "%Y-%m-%d %H:%M", localtime((const time_t*)&s.st_mtime)); - date[31] = 0; - -// 12345678901234567890123456789012345678901234567890123456789012345678901234567890 -// MMMMMMMM UUUUUUUU GGGGGGGGG XXXXXXXX YYYY-MM-DD HH:MM NAME (->LINK) - - switch(s.st_mode & S_IFMT) { - case S_IFBLK: - case S_IFCHR: - printf("%s %-8s %-8s %3d, %3d %s %s\n", - mode, user, group, - (int) MAJOR(s.st_rdev), (int) MINOR(s.st_rdev), - date, name); - break; - case S_IFREG: - printf("%s %-8s %-8s %8d %s %s\n", - mode, user, group, (int) s.st_size, date, name); - break; - case S_IFLNK: { - char linkto[256]; - int len; - - len = readlink(path, linkto, 256); - if(len < 0) return -1; - - if(len > 255) { - linkto[252] = '.'; - linkto[253] = '.'; - linkto[254] = '.'; - linkto[255] = 0; - } else { - linkto[len] = 0; - } - - printf("%s %-8s %-8s %s %s -> %s\n", - mode, user, group, date, name, linkto); - break; - } - default: - printf("%s %-8s %-8s %s %s\n", - mode, user, group, date, name); - - } - return 0; -} - -static int listdir(const char *name, int flags) -{ - char tmp[4096]; - DIR *d; - struct dirent *de; - - d = opendir(name); - if(d == 0) { - fprintf(stderr, "opendir failed, %s\n", strerror(errno)); - return -1; - } - - while((de = readdir(d)) != 0){ - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue; - if(de->d_name[0] == '.' && (flags & LIST_ALL) == 0) continue; - if ((flags & LIST_LONG) != 0) { - sprintf(tmp, "%s/%s", name, de->d_name); - listfile(tmp, flags); - } else { - printf("%s\n", de->d_name); - } - } - - if (flags & LIST_RECURSIVE) { - rewinddir(d); - - while ((de = readdir(d)) != 0) { - struct stat s; - int err; - - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; - if (de->d_name[0] == '.' && (flags & LIST_ALL) == 0) - continue; - - if (!strcmp(name, "/")) sprintf(tmp, "/%s", de->d_name); - else sprintf(tmp, "%s/%s", name, de->d_name); - - /* - * If the name ends in a '/', use stat() so we treat it like a - * directory even if it's a symlink. - */ - if (tmp[strlen(tmp)-1] == '/') - err = stat(tmp, &s); - else - err = lstat(tmp, &s); - - if (err < 0) { - perror(tmp); - closedir(d); - return -1; - } - - if (S_ISDIR(s.st_mode)) { - printf("\n%s:\n", tmp); - listdir(tmp, flags); - } - } - } - - closedir(d); - return 0; -} - -static int listpath(const char *name, int flags) -{ - struct stat s; - int err; - - /* - * If the name ends in a '/', use stat() so we treat it like a - * directory even if it's a symlink. - */ - if (name[strlen(name)-1] == '/') - err = stat(name, &s); - else - err = lstat(name, &s); - - if (err < 0) { - perror(name); - return -1; - } - - if (S_ISDIR(s.st_mode)) { - if (flags & LIST_RECURSIVE) - printf("\n%s:\n", name); - return listdir(name, flags); - } else { - if ((flags & LIST_LONG) != 0) { - /* yeah this calls stat() again*/ - return listfile(name, flags); - } else { - printf("%s\n", name); - return 0; - } - } -} - -int ls_main(int argc, char **argv) -{ - int flags = 0; - int listed = 0; - - if(argc > 1) { - int i; - int err = 0; - - for (i = 1; i < argc; i++) { - if(!strcmp(argv[i], "-l")) { - flags |= LIST_LONG; - } else if (!strcmp(argv[i], "-a")) { - flags |= LIST_ALL; - } else if (!strcmp(argv[i], "-R")) { - flags |= LIST_RECURSIVE; - } else { - listed++; - if(listpath(argv[i], flags) != 0) { - err = EXIT_FAILURE; - } - } - } - - if (listed > 0) return err; - } - - // list working directory if no files or directories were specified - return listpath(".", flags); -} diff --git a/toolbox/lsmod.c b/toolbox/lsmod.c deleted file mode 100644 index 8b55ee61bf7b48b40dce60277c4ef32fced1a2b9..0000000000000000000000000000000000000000 --- a/toolbox/lsmod.c +++ /dev/null @@ -1,10 +0,0 @@ -#include <stdio.h> - -extern int cat_main(int argc, char **argv); - -int lsmod_main(int argc, char **argv) -{ - char *cat_argv[] = { "cat", "/proc/modules", NULL }; - return cat_main(2, cat_argv); -} - diff --git a/toolbox/mkdir.c b/toolbox/mkdir.c deleted file mode 100644 index 121adab29d81832daa6a6e4d1000367ac4334519..0000000000000000000000000000000000000000 --- a/toolbox/mkdir.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -static int usage() -{ - fprintf(stderr,"mkdir <target>\n"); - return -1; -} - -int mkdir_main(int argc, char *argv[]) -{ - int symbolic = 0; - int ret; - if(argc < 2) return usage(); - - while(argc > 1) { - argc--; - argv++; - ret = mkdir(argv[0], 0777); - if(ret < 0) { - fprintf(stderr, "mkdir failed for %s, %s\n", argv[0], strerror(errno)); - return ret; - } - } - - return 0; -} diff --git a/toolbox/mkdosfs.c b/toolbox/mkdosfs.c deleted file mode 100644 index 9ba94090daf17440e3dd5e58b5062de89b845e89..0000000000000000000000000000000000000000 --- a/toolbox/mkdosfs.c +++ /dev/null @@ -1,849 +0,0 @@ -/* $NetBSD: newfs_msdos.c,v 1.18.2.1 2005/05/01 18:44:02 tron Exp $ */ - -/* - * Copyright (c) 1998 Robert Nordier - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``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 AUTHOR(S) 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. - */ - -#define __USE_FILE_OFFSET64 - -#include <sys/cdefs.h> - -#include <sys/types.h> -#include <sys/param.h> -#ifdef __FreeBSD__ -#include <sys/diskslice.h> -#endif -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/time.h> -#include <sys/ioctl.h> - -#include <ctype.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <paths.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> -#ifdef __NetBSD__ -#include <disktab.h> -#include <util.h> -#endif - -#define MAXU16 0xffff /* maximum unsigned 16-bit quantity */ -#define BPN 4 /* bits per nibble */ -#define NPB 2 /* nibbles per byte */ - -#define DOSMAGIC 0xaa55 /* DOS magic number */ -#define MINBPS 128 /* minimum bytes per sector */ -#define MAXSPC 128 /* maximum sectors per cluster */ -#define MAXNFT 16 /* maximum number of FATs */ -#define DEFBLK 4096 /* default block size */ -#define DEFBLK16 2048 /* default block size FAT16 */ -#define DEFRDE 512 /* default root directory entries */ -#define RESFTE 2 /* reserved FAT entries */ -#define MINCLS12 1 /* minimum FAT12 clusters */ -#define MINCLS16 0x1000 /* minimum FAT16 clusters */ -#define MINCLS32 2 /* minimum FAT32 clusters */ -#define MAXCLS12 0xfed /* maximum FAT12 clusters */ -#define MAXCLS16 0xfff5 /* maximum FAT16 clusters */ -#define MAXCLS32 0xffffff5 /* maximum FAT32 clusters */ - -#define mincls(fat) ((fat) == 12 ? MINCLS12 : \ - (fat) == 16 ? MINCLS16 : \ - MINCLS32) - -#define maxcls(fat) ((fat) == 12 ? MAXCLS12 : \ - (fat) == 16 ? MAXCLS16 : \ - MAXCLS32) - -#define mk1(p, x) \ - (p) = (u_int8_t)(x) - -#define mk2(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010) - -#define mk4(p, x) \ - (p)[0] = (u_int8_t)(x), \ - (p)[1] = (u_int8_t)((x) >> 010), \ - (p)[2] = (u_int8_t)((x) >> 020), \ - (p)[3] = (u_int8_t)((x) >> 030) - -#define argto1(arg, lo, msg) argtou(arg, lo, 0xff, msg) -#define argto2(arg, lo, msg) argtou(arg, lo, 0xffff, msg) -#define argto4(arg, lo, msg) argtou(arg, lo, 0xffffffff, msg) -#define argtox(arg, lo, msg) argtou(arg, lo, UINT_MAX, msg) - -#ifndef MAX -#define MAX(x, y) ((x) > (y) ? (x) : (y)) -#endif -#ifndef MIN -#define MIN(x, y) ((x) < (y) ? (x) : (y)) -#endif - -static int powerof2(int x) { - int i; - for (i = 0; i < 32; i++) { - if (x & 1) { - x >>= 1; - // if x is zero, then original x was a power of two - return (x == 0); - } - x >>= 1; - } - - return 0; -} - -#ifndef howmany -#define howmany(x, y) (((x)+((y)-1))/(y)) -#endif - -#pragma pack(push, 1) -struct bs { - u_int8_t jmp[3]; /* bootstrap entry point */ - u_int8_t oem[8]; /* OEM name and version */ -}; -#define BS_SIZE 11 - -struct bsbpb { - u_int8_t bps[2]; /* bytes per sector */ - u_int8_t spc; /* sectors per cluster */ - u_int8_t res[2]; /* reserved sectors */ - u_int8_t nft; /* number of FATs */ - u_int8_t rde[2]; /* root directory entries */ - u_int8_t sec[2]; /* total sectors */ - u_int8_t mid; /* media descriptor */ - u_int8_t spf[2]; /* sectors per FAT */ - u_int8_t spt[2]; /* sectors per track */ - u_int8_t hds[2]; /* drive heads */ - u_int8_t hid[4]; /* hidden sectors */ - u_int8_t bsec[4]; /* big total sectors */ -}; -#define BSBPB_SIZE 25 - -struct bsxbpb { - u_int8_t bspf[4]; /* big sectors per FAT */ - u_int8_t xflg[2]; /* FAT control flags */ - u_int8_t vers[2]; /* file system version */ - u_int8_t rdcl[4]; /* root directory start cluster */ - u_int8_t infs[2]; /* file system info sector */ - u_int8_t bkbs[2]; /* backup boot sector */ - u_int8_t rsvd[12]; /* reserved */ -}; -#define BSXBPB_SIZE 28 - -struct bsx { - u_int8_t drv; /* drive number */ - u_int8_t rsvd; /* reserved */ - u_int8_t sig; /* extended boot signature */ - u_int8_t volid[4]; /* volume ID number */ - u_int8_t label[11]; /* volume label */ - u_int8_t type[8]; /* file system type */ -}; -#define BSX_SIZE 26 - -struct de { - u_int8_t namext[11]; /* name and extension */ - u_int8_t attr; /* attributes */ - u_int8_t rsvd[10]; /* reserved */ - u_int8_t time[2]; /* creation time */ - u_int8_t date[2]; /* creation date */ - u_int8_t clus[2]; /* starting cluster */ - u_int8_t size[4]; /* size */ -#define DE_SIZE 32 -}; -#pragma pack(pop) - -struct bpb { - u_int bps; /* bytes per sector */ - u_int spc; /* sectors per cluster */ - u_int res; /* reserved sectors */ - u_int nft; /* number of FATs */ - u_int rde; /* root directory entries */ - u_int sec; /* total sectors */ - u_int mid; /* media descriptor */ - u_int spf; /* sectors per FAT */ - u_int spt; /* sectors per track */ - u_int hds; /* drive heads */ - u_int hid; /* hidden sectors */ - u_int bsec; /* big total sectors */ - u_int bspf; /* big sectors per FAT */ - u_int rdcl; /* root directory start cluster */ - u_int infs; /* file system info sector */ - u_int bkbs; /* backup boot sector */ -}; - -static u_int8_t bootcode[] = { - 0xfa, /* cli */ - 0x31, 0xc0, /* xor ax,ax */ - 0x8e, 0xd0, /* mov ss,ax */ - 0xbc, 0x00, 0x7c, /* mov sp,7c00h */ - 0xfb, /* sti */ - 0x8e, 0xd8, /* mov ds,ax */ - 0xe8, 0x00, 0x00, /* call $ + 3 */ - 0x5e, /* pop si */ - 0x83, 0xc6, 0x19, /* add si,+19h */ - 0xbb, 0x07, 0x00, /* mov bx,0007h */ - 0xfc, /* cld */ - 0xac, /* lodsb */ - 0x84, 0xc0, /* test al,al */ - 0x74, 0x06, /* jz $ + 8 */ - 0xb4, 0x0e, /* mov ah,0eh */ - 0xcd, 0x10, /* int 10h */ - 0xeb, 0xf5, /* jmp $ - 9 */ - 0x30, 0xe4, /* xor ah,ah */ - 0xcd, 0x16, /* int 16h */ - 0xcd, 0x19, /* int 19h */ - 0x0d, 0x0a, - 'N', 'o', 'n', '-', 's', 'y', 's', 't', - 'e', 'm', ' ', 'd', 'i', 's', 'k', - 0x0d, 0x0a, - 'P', 'r', 'e', 's', 's', ' ', 'a', 'n', - 'y', ' ', 'k', 'e', 'y', ' ', 't', 'o', - ' ', 'r', 'e', 'b', 'o', 'o', 't', - 0x0d, 0x0a, - 0 -}; - -static void print_bpb(struct bpb *); -static u_int ckgeom(const char *, u_int, const char *); -static u_int argtou(const char *, u_int, u_int, const char *); -static int oklabel(const char *); -static void mklabel(u_int8_t *, const char *); -static void setstr(u_int8_t *, const char *, size_t); -static void usage(char* progname); - -/* - * Construct a FAT12, FAT16, or FAT32 file system. - */ -int -mkdosfs_main(int argc, char *argv[]) -{ - static char opts[] = "NB:F:I:L:O:S:a:b:c:e:f:h:i:k:m:n:o:r:s:u:"; - static const char *opt_B, *opt_L, *opt_O; - static u_int opt_F, opt_I, opt_S, opt_a, opt_b, opt_c, opt_e; - static u_int opt_h, opt_i, opt_k, opt_m, opt_n, opt_o, opt_r; - static u_int opt_s, opt_u; - static int opt_N; - static int Iflag, mflag, oflag; - char buf[MAXPATHLEN]; - struct stat sb; - struct timeval tv; - struct bpb bpb; - struct tm *tm; - struct bs *bs; - struct bsbpb *bsbpb; - struct bsxbpb *bsxbpb; - struct bsx *bsx; - struct de *de; - u_int8_t *img; - const char *fname, *dtype, *bname; - ssize_t n; - time_t now; - u_int fat, bss, rds, cls, dir, lsn, x, x1, x2; - int ch, fd, fd1; - char* progname = argv[0]; - - while ((ch = getopt(argc, argv, opts)) != -1) - switch (ch) { - case 'N': - opt_N = 1; - break; - case 'B': - opt_B = optarg; - break; - case 'F': - if (strcmp(optarg, "12") && - strcmp(optarg, "16") && - strcmp(optarg, "32")) - fprintf(stderr, "%s: bad FAT type\n", optarg); - opt_F = atoi(optarg); - break; - case 'I': - opt_I = argto4(optarg, 0, "volume ID"); - Iflag = 1; - break; - case 'L': - if (!oklabel(optarg)) - fprintf(stderr, "%s: bad volume label\n", optarg); - opt_L = optarg; - break; - case 'O': - if (strlen(optarg) > 8) - fprintf(stderr, "%s: bad OEM string\n", optarg); - opt_O = optarg; - break; - case 'S': - opt_S = argto2(optarg, 1, "bytes/sector"); - break; - case 'a': - opt_a = argto4(optarg, 1, "sectors/FAT"); - break; - case 'b': - opt_b = argtox(optarg, 1, "block size"); - opt_c = 0; - break; - case 'c': - opt_c = argto1(optarg, 1, "sectors/cluster"); - opt_b = 0; - break; - case 'e': - opt_e = argto2(optarg, 1, "directory entries"); - break; - case 'h': - opt_h = argto2(optarg, 1, "drive heads"); - break; - case 'i': - opt_i = argto2(optarg, 1, "info sector"); - break; - case 'k': - opt_k = argto2(optarg, 1, "backup sector"); - break; - case 'm': - opt_m = argto1(optarg, 0, "media descriptor"); - mflag = 1; - break; - case 'n': - opt_n = argto1(optarg, 1, "number of FATs"); - break; - case 'o': - opt_o = argto4(optarg, 0, "hidden sectors"); - oflag = 1; - break; - case 'r': - opt_r = argto2(optarg, 1, "reserved sectors"); - break; - case 's': - opt_s = argto4(optarg, 1, "file system size"); - break; - case 'u': - opt_u = argto2(optarg, 1, "sectors/track"); - break; - default: - usage(progname); - } - argc -= optind; - argv += optind; - if (argc < 1 || argc > 2) - usage(progname); - fname = *argv++; - if (!strchr(fname, '/')) { - snprintf(buf, sizeof(buf), "%sr%s", _PATH_DEV, fname); - if (!(fname = strdup(buf))) - fprintf(stderr, NULL); - } - dtype = *argv; - if ((fd = open(fname, opt_N ? O_RDONLY : O_RDWR)) == -1 || - fstat(fd, &sb)) - fprintf(stderr, "%s\n", fname); - memset(&bpb, 0, sizeof(bpb)); - - if (opt_h) - bpb.hds = opt_h; - if (opt_u) - bpb.spt = opt_u; - if (opt_S) - bpb.bps = opt_S; - if (opt_s) - bpb.bsec = opt_s; - if (oflag) - bpb.hid = opt_o; - - bpb.bps = 512; // 512 bytes/sector - bpb.spc = 8; // 4K clusters - - - fprintf(stderr, "opening %s\n", fname); - if ((fd1 = open(fname, O_RDONLY)) == -1) { - fprintf(stderr, "failed to open %s\n", fname); - exit(1); - } - - lseek(fd1, 0, SEEK_SET); - off_t length = lseek(fd1, 0, SEEK_END); - fprintf(stderr, "lseek returned %ld\n", length); - if (length > 0) { - bpb.bsec = length / bpb.bps; - bpb.spt = bpb.bsec; - // use FAT32 for 2 gig or greater - if (length >= 2 *1024 *1024 *1024) { - fat = 32; - } else { - fat = 16; - } - } - close(fd1); - fd1 = -1; - - if (!powerof2(bpb.bps)) - fprintf(stderr, "bytes/sector (%u) is not a power of 2\n", bpb.bps); - if (bpb.bps < MINBPS) - fprintf(stderr, "bytes/sector (%u) is too small; minimum is %u\n", - bpb.bps, MINBPS); - - if (!(fat = opt_F)) { - if (!opt_e && (opt_i || opt_k)) - fat = 32; - } - - if ((fat == 32 && opt_e) || (fat != 32 && (opt_i || opt_k))) - fprintf(stderr, "-%c is not a legal FAT%s option\n", - fat == 32 ? 'e' : opt_i ? 'i' : 'k', - fat == 32 ? "32" : "12/16"); - if (fat == 32) - bpb.rde = 0; - if (opt_b) { - if (!powerof2(opt_b)) - fprintf(stderr, "block size (%u) is not a power of 2\n", opt_b); - if (opt_b < bpb.bps) - fprintf(stderr, "block size (%u) is too small; minimum is %u\n", - opt_b, bpb.bps); - if (opt_b > bpb.bps * MAXSPC) - fprintf(stderr, "block size (%u) is too large; maximum is %u\n", - opt_b, bpb.bps * MAXSPC); - bpb.spc = opt_b / bpb.bps; - } - if (opt_c) { - if (!powerof2(opt_c)) - fprintf(stderr, "sectors/cluster (%u) is not a power of 2\n", opt_c); - bpb.spc = opt_c; - } - if (opt_r) - bpb.res = opt_r; - if (opt_n) { - if (opt_n > MAXNFT) - fprintf(stderr, "number of FATs (%u) is too large; maximum is %u\n", - opt_n, MAXNFT); - bpb.nft = opt_n; - } - if (opt_e) - bpb.rde = opt_e; - if (mflag) { - if (opt_m < 0xf0) - fprintf(stderr, "illegal media descriptor (%#x)\n", opt_m); - bpb.mid = opt_m; - } - if (opt_a) - bpb.bspf = opt_a; - if (opt_i) - bpb.infs = opt_i; - if (opt_k) - bpb.bkbs = opt_k; - bss = 1; - bname = NULL; - fd1 = -1; - if (opt_B) { - bname = opt_B; - if (!strchr(bname, '/')) { - snprintf(buf, sizeof(buf), "/boot/%s", bname); - if (!(bname = strdup(buf))) - fprintf(stderr, NULL); - } - if ((fd1 = open(bname, O_RDONLY)) == -1 || fstat(fd1, &sb)) - fprintf(stderr, "%s", bname); - if (!S_ISREG(sb.st_mode) || sb.st_size % bpb.bps || - sb.st_size < bpb.bps || sb.st_size > bpb.bps * MAXU16) - fprintf(stderr, "%s: inappropriate file type or format\n", bname); - bss = sb.st_size / bpb.bps; - } - if (!bpb.nft) - bpb.nft = 2; - if (!fat) { - if (bpb.bsec < (bpb.res ? bpb.res : bss) + - howmany((RESFTE + (bpb.spc ? MINCLS16 : MAXCLS12 + 1)) * - ((bpb.spc ? 16 : 12) / BPN), bpb.bps * NPB) * - bpb.nft + - howmany(bpb.rde ? bpb.rde : DEFRDE, - bpb.bps / DE_SIZE) + - (bpb.spc ? MINCLS16 : MAXCLS12 + 1) * - (bpb.spc ? bpb.spc : howmany(DEFBLK, bpb.bps))) - fat = 12; - else if (bpb.rde || bpb.bsec < - (bpb.res ? bpb.res : bss) + - howmany((RESFTE + MAXCLS16) * 2, bpb.bps) * bpb.nft + - howmany(DEFRDE, bpb.bps / DE_SIZE) + - (MAXCLS16 + 1) * - (bpb.spc ? bpb.spc : howmany(8192, bpb.bps))) - fat = 16; - else - fat = 32; - } - x = bss; - if (fat == 32) { - if (!bpb.infs) { - if (x == MAXU16 || x == bpb.bkbs) - fprintf(stderr, "no room for info sector\n"); - bpb.infs = x; - } - if (bpb.infs != MAXU16 && x <= bpb.infs) - x = bpb.infs + 1; - if (!bpb.bkbs) { - if (x == MAXU16) - fprintf(stderr, "no room for backup sector\n"); - bpb.bkbs = x; - } else if (bpb.bkbs != MAXU16 && bpb.bkbs == bpb.infs) - fprintf(stderr, "backup sector would overwrite info sector\n"); - if (bpb.bkbs != MAXU16 && x <= bpb.bkbs) - x = bpb.bkbs + 1; - } - if (!bpb.res) - bpb.res = fat == 32 ? MAX(x, MAX(16384 / bpb.bps, 4)) : x; - else if (bpb.res < x) - fprintf(stderr, "too few reserved sectors (need %d have %d)\n", x, bpb.res); - if (fat != 32 && !bpb.rde) - bpb.rde = DEFRDE; - rds = howmany(bpb.rde, bpb.bps / DE_SIZE); - if (!bpb.spc) - for (bpb.spc = howmany(fat == 16 ? DEFBLK16 : DEFBLK, bpb.bps); - bpb.spc < MAXSPC && - bpb.res + - howmany((RESFTE + maxcls(fat)) * (fat / BPN), - bpb.bps * NPB) * bpb.nft + - rds + - (u_int64_t)(maxcls(fat) + 1) * bpb.spc <= bpb.bsec; - bpb.spc <<= 1); - if (fat != 32 && bpb.bspf > MAXU16) - fprintf(stderr, "too many sectors/FAT for FAT12/16\n"); - x1 = bpb.res + rds; - x = bpb.bspf ? bpb.bspf : 1; - if (x1 + (u_int64_t)x * bpb.nft > bpb.bsec) - fprintf(stderr, "meta data exceeds file system size\n"); - x1 += x * bpb.nft; - x = (u_int64_t)(bpb.bsec - x1) * bpb.bps * NPB / - (bpb.spc * bpb.bps * NPB + fat / BPN * bpb.nft); - x2 = howmany((RESFTE + MIN(x, maxcls(fat))) * (fat / BPN), - bpb.bps * NPB); - if (!bpb.bspf) { - bpb.bspf = x2; - x1 += (bpb.bspf - 1) * bpb.nft; - } - cls = (bpb.bsec - x1) / bpb.spc; - x = (u_int64_t)bpb.bspf * bpb.bps * NPB / (fat / BPN) - RESFTE; - if (cls > x) - cls = x; - if (bpb.bspf < x2) - fprintf(stderr, "warning: sectors/FAT limits file system to %u clusters\n", - cls); - if (cls < mincls(fat)) - fprintf(stderr, "%u clusters too few clusters for FAT%u, need %u\n", cls, fat, - mincls(fat)); - if (cls > maxcls(fat)) { - cls = maxcls(fat); - bpb.bsec = x1 + (cls + 1) * bpb.spc - 1; - fprintf(stderr, "warning: FAT type limits file system to %u sectors\n", - bpb.bsec); - } - printf("%s: %u sector%s in %u FAT%u cluster%s " - "(%u bytes/cluster)\n", fname, cls * bpb.spc, - cls * bpb.spc == 1 ? "" : "s", cls, fat, - cls == 1 ? "" : "s", bpb.bps * bpb.spc); - if (!bpb.mid) - bpb.mid = !bpb.hid ? 0xf0 : 0xf8; - if (fat == 32) - bpb.rdcl = RESFTE; - if (bpb.hid + bpb.bsec <= MAXU16) { - bpb.sec = bpb.bsec; - bpb.bsec = 0; - } - if (fat != 32) { - bpb.spf = bpb.bspf; - bpb.bspf = 0; - } - ch = 0; - if (fat == 12) - ch = 1; /* 001 Primary DOS with 12 bit FAT */ - else if (fat == 16) { - if (bpb.bsec == 0) - ch = 4; /* 004 Primary DOS with 16 bit FAT <32M */ - else - ch = 6; /* 006 Primary 'big' DOS, 16-bit FAT (> 32MB) */ - /* - * XXX: what about: - * 014 DOS (16-bit FAT) - LBA - * ? - */ - } else if (fat == 32) { - ch = 11; /* 011 Primary DOS with 32 bit FAT */ - /* - * XXX: what about: - * 012 Primary DOS with 32 bit FAT - LBA - * ? - */ - } - if (ch != 0) - printf("MBR type: %d\n", ch); - print_bpb(&bpb); - if (!opt_N) { - gettimeofday(&tv, NULL); - now = tv.tv_sec; - tm = localtime(&now); - if (!(img = malloc(bpb.bps))) - fprintf(stderr, NULL); - dir = bpb.res + (bpb.spf ? bpb.spf : bpb.bspf) * bpb.nft; - - for (lsn = 0; lsn < dir + (fat == 32 ? bpb.spc : rds); lsn++) { - x = lsn; - if (opt_B && - fat == 32 && bpb.bkbs != MAXU16 && - bss <= bpb.bkbs && x >= bpb.bkbs) { - x -= bpb.bkbs; - if (!x && lseek(fd1, 0, SEEK_SET)) - fprintf(stderr, "lseek failed for %s\n", bname); - } - if (opt_B && x < bss) { - if ((n = read(fd1, img, bpb.bps)) == -1) - fprintf(stderr, "%s\n", bname); - if (n != bpb.bps) - fprintf(stderr, "%s: can't read sector %u\n", bname, x); - } else - memset(img, 0, bpb.bps); - if (!lsn || - (fat == 32 && bpb.bkbs != MAXU16 && lsn == bpb.bkbs)) { - x1 = BS_SIZE; - bsbpb = (struct bsbpb *)(img + x1); - mk2(bsbpb->bps, bpb.bps); - mk1(bsbpb->spc, bpb.spc); - mk2(bsbpb->res, bpb.res); - mk1(bsbpb->nft, bpb.nft); - mk2(bsbpb->rde, bpb.rde); - mk2(bsbpb->sec, bpb.sec); - mk1(bsbpb->mid, bpb.mid); - mk2(bsbpb->spf, bpb.spf); - mk2(bsbpb->spt, bpb.spt); - mk2(bsbpb->hds, bpb.hds); - mk4(bsbpb->hid, bpb.hid); - mk4(bsbpb->bsec, bpb.bsec); - x1 += BSBPB_SIZE; - if (fat == 32) { - bsxbpb = (struct bsxbpb *)(img + x1); - mk4(bsxbpb->bspf, bpb.bspf); - mk2(bsxbpb->xflg, 0); - mk2(bsxbpb->vers, 0); - mk4(bsxbpb->rdcl, bpb.rdcl); - mk2(bsxbpb->infs, bpb.infs); - mk2(bsxbpb->bkbs, bpb.bkbs); - x1 += BSXBPB_SIZE; - } - bsx = (struct bsx *)(img + x1); - mk1(bsx->sig, 0x29); - if (Iflag) - x = opt_I; - else - x = (((u_int)(1 + tm->tm_mon) << 8 | - (u_int)tm->tm_mday) + - ((u_int)tm->tm_sec << 8 | - (u_int)(tv.tv_usec / 10))) << 16 | - ((u_int)(1900 + tm->tm_year) + - ((u_int)tm->tm_hour << 8 | - (u_int)tm->tm_min)); - mk4(bsx->volid, x); - mklabel(bsx->label, opt_L ? opt_L : "NO_NAME"); - snprintf(buf, sizeof(buf), "FAT%u", fat); - setstr(bsx->type, buf, sizeof(bsx->type)); - if (!opt_B) { - x1 += BSX_SIZE; - bs = (struct bs *)img; - mk1(bs->jmp[0], 0xeb); - mk1(bs->jmp[1], x1 - 2); - mk1(bs->jmp[2], 0x90); - setstr(bs->oem, opt_O ? opt_O : "NetBSD", - sizeof(bs->oem)); - memcpy(img + x1, bootcode, sizeof(bootcode)); - mk2(img + bpb.bps - 2, DOSMAGIC); - } - } else if (fat == 32 && bpb.infs != MAXU16 && - (lsn == bpb.infs || - (bpb.bkbs != MAXU16 && - lsn == bpb.bkbs + bpb.infs))) { - mk4(img, 0x41615252); - mk4(img + bpb.bps - 28, 0x61417272); - mk4(img + bpb.bps - 24, 0xffffffff); - mk4(img + bpb.bps - 20, bpb.rdcl); - mk2(img + bpb.bps - 2, DOSMAGIC); - } else if (lsn >= bpb.res && lsn < dir && - !((lsn - bpb.res) % - (bpb.spf ? bpb.spf : bpb.bspf))) { - mk1(img[0], bpb.mid); - for (x = 1; x < fat * (fat == 32 ? 3 : 2) / 8; x++) - mk1(img[x], fat == 32 && x % 4 == 3 ? 0x0f : 0xff); - } else if (lsn == dir && opt_L) { - de = (struct de *)img; - mklabel(de->namext, opt_L); - mk1(de->attr, 050); - x = (u_int)tm->tm_hour << 11 | - (u_int)tm->tm_min << 5 | - (u_int)tm->tm_sec >> 1; - mk2(de->time, x); - x = (u_int)(tm->tm_year - 80) << 9 | - (u_int)(tm->tm_mon + 1) << 5 | - (u_int)tm->tm_mday; - mk2(de->date, x); - } - if ((n = write(fd, img, bpb.bps)) == -1) - fprintf(stderr, "%s\n", fname); - if (n != bpb.bps) - fprintf(stderr, "%s: can't write sector %u\n", fname, lsn); - } - } - return 0; -} - -/* - * Print out BPB values. - */ -static void -print_bpb(struct bpb *bpb) -{ - printf("bps=%u spc=%u res=%u nft=%u", bpb->bps, bpb->spc, bpb->res, - bpb->nft); - if (bpb->rde) - printf(" rde=%u", bpb->rde); - if (bpb->sec) - printf(" sec=%u", bpb->sec); - printf(" mid=%#x", bpb->mid); - if (bpb->spf) - printf(" spf=%u", bpb->spf); - printf(" spt=%u hds=%u hid=%u", bpb->spt, bpb->hds, bpb->hid); - if (bpb->bsec) - printf(" bsec=%u", bpb->bsec); - if (!bpb->spf) { - printf(" bspf=%u rdcl=%u", bpb->bspf, bpb->rdcl); - printf(" infs="); - printf(bpb->infs == MAXU16 ? "%#x" : "%u", bpb->infs); - printf(" bkbs="); - printf(bpb->bkbs == MAXU16 ? "%#x" : "%u", bpb->bkbs); - } - printf("\n"); -} - -/* - * Check a disk geometry value. - */ -static u_int -ckgeom(const char *fname, u_int val, const char *msg) -{ - if (!val) - fprintf(stderr, "%s: no default %s\n", fname, msg); - if (val > MAXU16) - fprintf(stderr, "%s: illegal %s\n", fname, msg); - return val; -} - -/* - * Convert and check a numeric option argument. - */ -static u_int -argtou(const char *arg, u_int lo, u_int hi, const char *msg) -{ - char *s; - u_long x; - - errno = 0; - x = strtoul(arg, &s, 0); - if (errno || !*arg || *s || x < lo || x > hi) - fprintf(stderr, "%s: bad %s\n", arg, msg); - return x; -} - -/* - * Check a volume label. - */ -static int -oklabel(const char *src) -{ - int c, i; - - for (i = 0; i <= 11; i++) { - c = (u_char)*src++; - if (c < ' ' + !i || strchr("\"*+,./:;<=>?[\\]|", c)) - break; - } - return i && !c; -} - -/* - * Make a volume label. - */ -static void -mklabel(u_int8_t *dest, const char *src) -{ - int c, i; - - for (i = 0; i < 11; i++) { - c = *src ? toupper((unsigned char)*src++) : ' '; - *dest++ = !i && c == '\xe5' ? 5 : c; - } -} - -/* - * Copy string, padding with spaces. - */ -static void -setstr(u_int8_t *dest, const char *src, size_t len) -{ - while (len--) - *dest++ = *src ? *src++ : ' '; -} - -/* - * Print usage message. - */ -static void -usage(char* progname) -{ - fprintf(stderr, - "usage: %s [ -options ] special [disktype]\n", progname); - fprintf(stderr, "where the options are:\n"); - fprintf(stderr, "\t-N don't create file system: " - "just print out parameters\n"); - fprintf(stderr, "\t-B get bootstrap from file\n"); - fprintf(stderr, "\t-F FAT type (12, 16, or 32)\n"); - fprintf(stderr, "\t-I volume ID\n"); - fprintf(stderr, "\t-L volume label\n"); - fprintf(stderr, "\t-O OEM string\n"); - fprintf(stderr, "\t-S bytes/sector\n"); - fprintf(stderr, "\t-a sectors/FAT\n"); - fprintf(stderr, "\t-b block size\n"); - fprintf(stderr, "\t-c sectors/cluster\n"); - fprintf(stderr, "\t-e root directory entries\n"); - fprintf(stderr, "\t-h drive heads\n"); - fprintf(stderr, "\t-i file system info sector\n"); - fprintf(stderr, "\t-k backup boot sector\n"); - fprintf(stderr, "\t-m media descriptor\n"); - fprintf(stderr, "\t-n number of FATs\n"); - fprintf(stderr, "\t-o hidden sectors\n"); - fprintf(stderr, "\t-r reserved sectors\n"); - fprintf(stderr, "\t-s file system size (sectors)\n"); - fprintf(stderr, "\t-u sectors/track\n"); - exit(1); -} - - diff --git a/toolbox/mount.c b/toolbox/mount.c deleted file mode 100644 index ef13e1fd5337366e3b7ada71df888db429ebd5ab..0000000000000000000000000000000000000000 --- a/toolbox/mount.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * mount.c, by rmk - */ - -#include <sys/mount.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <linux/loop.h> - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) - -// FIXME - only one loop mount is supported at a time -#define LOOP_DEVICE "/dev/block/loop0" - -struct mount_opts { - const char str[8]; - unsigned long rwmask; - unsigned long rwset; - unsigned long rwnoset; -}; - -struct extra_opts { - char *str; - char *end; - int used_size; - int alloc_size; -}; - -/* - * These options define the function of "mount(2)". - */ -#define MS_TYPE (MS_REMOUNT|MS_BIND|MS_MOVE) - - -static const struct mount_opts options[] = { - /* name mask set noset */ - { "async", MS_SYNCHRONOUS, 0, MS_SYNCHRONOUS }, - { "atime", MS_NOATIME, 0, MS_NOATIME }, - { "bind", MS_TYPE, MS_BIND, 0, }, - { "dev", MS_NODEV, 0, MS_NODEV }, - { "diratime", MS_NODIRATIME, 0, MS_NODIRATIME }, - { "dirsync", MS_DIRSYNC, MS_DIRSYNC, 0 }, - { "exec", MS_NOEXEC, 0, MS_NOEXEC }, - { "move", MS_TYPE, MS_MOVE, 0 }, - { "recurse", MS_REC, MS_REC, 0 }, - { "remount", MS_TYPE, MS_REMOUNT, 0 }, - { "ro", MS_RDONLY, MS_RDONLY, 0 }, - { "rw", MS_RDONLY, 0, MS_RDONLY }, - { "suid", MS_NOSUID, 0, MS_NOSUID }, - { "sync", MS_SYNCHRONOUS, MS_SYNCHRONOUS, 0 }, - { "verbose", MS_VERBOSE, MS_VERBOSE, 0 }, -}; - -static void add_extra_option(struct extra_opts *extra, char *s) -{ - int len = strlen(s); - int newlen = extra->used_size + len; - - if (extra->str) - len++; /* +1 for ',' */ - - if (newlen >= extra->alloc_size) { - char *new; - - new = realloc(extra->str, newlen + 1); /* +1 for NUL */ - if (!new) - return; - - extra->str = new; - extra->end = extra->str + extra->used_size; - extra->alloc_size = newlen; - } - - if (extra->used_size) { - *extra->end = ','; - extra->end++; - } - strcpy(extra->end, s); - extra->used_size += len; - -} - -static unsigned long -parse_mount_options(char *arg, unsigned long rwflag, struct extra_opts *extra, int* loop) -{ - char *s; - - *loop = 0; - while ((s = strsep(&arg, ",")) != NULL) { - char *opt = s; - unsigned int i; - int res, no = s[0] == 'n' && s[1] == 'o'; - - if (no) - s += 2; - - if (strcmp(s, "loop") == 0) { - *loop = 1; - continue; - } - for (i = 0, res = 1; i < ARRAY_SIZE(options); i++) { - res = strcmp(s, options[i].str); - - if (res == 0) { - rwflag &= ~options[i].rwmask; - if (no) - rwflag |= options[i].rwnoset; - else - rwflag |= options[i].rwset; - } - if (res <= 0) - break; - } - - if (res != 0 && s[0]) - add_extra_option(extra, opt); - } - - return rwflag; -} - -static char *progname; - -static struct extra_opts extra; -static unsigned long rwflag; - -static int -do_mount(char *dev, char *dir, char *type, unsigned long rwflag, void *data, int loop) -{ - char *s; - int error = 0; - - if (loop) { - int file_fd, device_fd; - - // FIXME - only one loop mount supported at a time - file_fd = open(dev, O_RDWR); - if (file_fd < -1) { - perror("open backing file failed"); - return 1; - } - device_fd = open(LOOP_DEVICE, O_RDWR); - if (device_fd < -1) { - perror("open loop device failed"); - close(file_fd); - return 1; - } - if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) { - perror("ioctl LOOP_SET_FD failed"); - close(file_fd); - close(device_fd); - return 1; - } - - close(file_fd); - close(device_fd); - dev = LOOP_DEVICE; - } - - while ((s = strsep(&type, ",")) != NULL) { -retry: - if (mount(dev, dir, s, rwflag, data) == -1) { - error = errno; - /* - * If the filesystem is not found, or the - * superblock is invalid, try the next. - */ - if (error == ENODEV || error == EINVAL) - continue; - - /* - * If we get EACCESS, and we're trying to - * mount readwrite and this isn't a remount, - * try read only. - */ - if (error == EACCES && - (rwflag & (MS_REMOUNT|MS_RDONLY)) == 0) { - rwflag |= MS_RDONLY; - goto retry; - } - break; - } - } - - if (error) { - errno = error; - perror("mount"); - return 255; - } - - return 0; -} - -static int print_mounts() -{ - FILE* f; - int length; - char buffer[100]; - - f = fopen("/proc/mounts", "r"); - if (!f) { - fprintf(stdout, "could not open /proc/mounts\n"); - return -1; - } - - do { - length = fread(buffer, 1, 100, f); - if (length > 0) - fwrite(buffer, 1, length, stdout); - } while (length > 0); - - fclose(f); - return 0; -} - -int mount_main(int argc, char *argv[]) -{ - char *type = NULL; - int c; - int loop; - - progname = argv[0]; - rwflag = MS_VERBOSE; - - // mount with no arguments is equivalent to "cat /proc/mounts" - if (argc == 1) return print_mounts(); - - do { - c = getopt(argc, argv, "o:rt:w"); - if (c == EOF) - break; - switch (c) { - case 'o': - rwflag = parse_mount_options(optarg, rwflag, &extra, &loop); - break; - case 'r': - rwflag |= MS_RDONLY; - break; - case 't': - type = optarg; - break; - case 'w': - rwflag &= ~MS_RDONLY; - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - progname, optopt); - exit(1); - } - } while (1); - - /* - * If remount, bind or move was specified, then we don't - * have a "type" as such. Use the dummy "none" type. - */ - if (rwflag & MS_TYPE) - type = "none"; - - if (optind + 2 != argc || type == NULL) { - fprintf(stderr, "Usage: %s [-r] [-w] [-o options] [-t type] " - "device directory\n", progname); - exit(1); - } - - return do_mount(argv[optind], argv[optind + 1], type, rwflag, - extra.str, loop); -} diff --git a/toolbox/mv.c b/toolbox/mv.c deleted file mode 100644 index a5bc2252a78e55a8486120285779baff6e1d8532..0000000000000000000000000000000000000000 --- a/toolbox/mv.c +++ /dev/null @@ -1,59 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/types.h> - - -int mv_main(int argc, char *argv[]) -{ - const char* dest; - struct stat st; - int i; - - if (argc < 3) { - fprintf(stderr,"USAGE: %s <source...> <destination>\n", argv[0]); - return -1; - } - - /* check if destination exists */ - dest = argv[argc - 1]; - if (stat(dest, &st)) { - /* an error, unless the destination was missing */ - if (errno != ENOENT) { - fprintf(stderr, "failed on %s - %s\n", dest, strerror(errno)); - return -1; - } - st.st_mode = 0; - } - - for (i = 1; i < argc - 1; i++) { - const char *source = argv[i]; - char fullDest[PATH_MAX + 1 + PATH_MAX + 1]; - /* assume we build "dest/source", and let rename() fail on pathsize */ - if (strlen(dest) + 1 + strlen(source) + 1 > sizeof(fullDest)) { - fprintf(stderr, "path too long\n"); - return -1; - } - strcpy(fullDest, dest); - - /* if destination is a directory, concat the source file name */ - if (S_ISDIR(st.st_mode)) { - const char *fileName = strrchr(source, '/'); - if (fullDest[strlen(fullDest)-1] != '/') { - strcat(fullDest, "/"); - } - strcat(fullDest, fileName ? fileName + 1 : source); - } - - /* attempt to move it */ - if (rename(source, fullDest)) { - fprintf(stderr, "failed on '%s' - %s\n", source, strerror(errno)); - return -1; - } - } - - return 0; -} - diff --git a/toolbox/netstat.c b/toolbox/netstat.c deleted file mode 100644 index 6404309257fc6ccb40bfe5ec3b6457e458961422..0000000000000000000000000000000000000000 --- a/toolbox/netstat.c +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <stdlib.h> - -typedef union iaddr iaddr; - -union iaddr { - unsigned u; - unsigned char b[4]; -}; - -static const char *state2str(unsigned state) -{ - switch(state){ - case 0x1: return "ESTABLISHED"; - case 0x2: return "SYN_SENT"; - case 0x3: return "SYN_RECV"; - case 0x4: return "FIN_WAIT1"; - case 0x5: return "FIN_WAIT2"; - case 0x6: return "TIME_WAIT"; - case 0x7: return "CLOSE"; - case 0x8: return "CLOSE_WAIT"; - case 0x9: return "LAST_ACK"; - case 0xA: return "LISTEN"; - case 0xB: return "CLOSING"; - default: return "UNKNOWN"; - } -} - -void addr2str(iaddr addr, unsigned port, char *buf) -{ - if(port) { - snprintf(buf, 64, "%d.%d.%d.%d:%d", - addr.b[0], addr.b[1], addr.b[2], addr.b[3], port); - } else { - snprintf(buf, 64, "%d.%d.%d.%d:*", - addr.b[0], addr.b[1], addr.b[2], addr.b[3]); - } -} - -int netstat_main(int argc, char *argv[]) -{ - char buf[512]; - char lip[64]; - char rip[64]; - iaddr laddr, raddr; - unsigned lport, rport, state, txq, rxq, num; - int n; - FILE *fp; - - printf("Proto Recv-Q Send-Q Local Address Foreign Address State\n"); - - fp = fopen("/proc/net/tcp", "r"); - if(fp != 0) { - fgets(buf, 512, fp); - while(fgets(buf, 512, fp)){ - n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x", - &num, &laddr.u, &lport, &raddr.u, &rport, - &state, &txq, &rxq); - if(n == 8) { - addr2str(laddr, lport, lip); - addr2str(raddr, rport, rip); - - printf("tcp %6d %6d %-22s %-22s %s\n", - txq, rxq, lip, rip, - state2str(state)); - } - } - fclose(fp); - } - fp = fopen("/proc/net/udp", "r"); - if(fp != 0) { - fgets(buf, 512, fp); - while(fgets(buf, 512, fp)){ - n = sscanf(buf, " %d: %x:%x %x:%x %x %x:%x", - &num, &laddr.u, &lport, &raddr.u, &rport, - &state, &txq, &rxq); - if(n == 8) { - addr2str(laddr, lport, lip); - addr2str(raddr, rport, rip); - - printf("udp %6d %6d %-22s %-22s\n", - txq, rxq, lip, rip); - } - } - fclose(fp); - } - - return 0; -} diff --git a/toolbox/notify.c b/toolbox/notify.c deleted file mode 100644 index b1761d299c9bf18e4cac158b0a0e60de9cac9b68..0000000000000000000000000000000000000000 --- a/toolbox/notify.c +++ /dev/null @@ -1,144 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <sys/inotify.h> -#include <errno.h> - -int notify_main(int argc, char *argv[]) -{ - int c; - int nfd, ffd; - int res; - char event_buf[512]; - struct inotify_event *event; - int event_mask = IN_ALL_EVENTS; - int event_count = 1; - int print_files = 0; - int verbose = 2; - int width = 80; - char **file_names; - int file_count; - int id_offset = 0; - int i; - char *buf; - - do { - c = getopt(argc, argv, "m:c:pv:w:"); - if (c == EOF) - break; - switch (c) { - case 'm': - event_mask = strtol(optarg, NULL, 0); - break; - case 'c': - event_count = atoi(optarg); - break; - case 'p': - print_files = 1; - break; - case 'v': - verbose = atoi(optarg); - break; - case 'w': - width = atoi(optarg); - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if (argc <= optind) { - fprintf(stderr, "Usage: %s [-m eventmask] [-c count] [-p] [-v verbosity] path [path ...]\n", argv[0]); - return 1; - } - - nfd = inotify_init(); - if(nfd < 0) { - fprintf(stderr, "inotify_init failed, %s\n", strerror(errno)); - return 1; - } - file_names = argv + optind; - file_count = argc - optind; - for(i = 0; i < file_count; i++) { - res = inotify_add_watch(nfd, file_names[i], event_mask); - if(res < 0) { - fprintf(stderr, "inotify_add_watch failed for %s, %s\n", file_names[i], strerror(errno)); - return 1; - } - if(i == 0) - id_offset = -res; - if(res + id_offset != i) { - fprintf(stderr, "%s got unexpected id %d instead of %d\n", file_names[i], res, i); - return 1; - } - } - - buf = malloc(width + 2); - - while(1) { - int event_pos = 0; - res = read(nfd, event_buf, sizeof(event_buf)); - if(res < (int)sizeof(*event)) { - if(errno == EINTR) - continue; - fprintf(stderr, "could not get event, %s\n", strerror(errno)); - return 1; - } - //printf("got %d bytes of event information\n", res); - while(res >= (int)sizeof(*event)) { - int event_size; - event = (struct inotify_event *)(event_buf + event_pos); - if(verbose >= 2) - printf("%s: %08x %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->cookie, event->len ? event->name : ""); - else if(verbose >= 2) - printf("%s: %08x \"%s\"\n", file_names[event->wd + id_offset], event->mask, event->len ? event->name : ""); - else if(verbose >= 1) - printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); - if(print_files && (event->mask & IN_MODIFY)) { - char filename[512]; - ssize_t read_len; - char *display_name; - int buflen; - strcpy(filename, file_names[event->wd + id_offset]); - if(event->len) { - strcat(filename, "/"); - strcat(filename, event->name); - } - ffd = open(filename, O_RDONLY); - display_name = (verbose >= 2 || event->len == 0) ? filename : event->name; - buflen = width - strlen(display_name); - read_len = read(ffd, buf, buflen); - if(read_len > 0) { - if(read_len < buflen && buf[read_len-1] != '\n') { - buf[read_len] = '\n'; - read_len++; - } - if(read_len == buflen) { - buf[--read_len] = '\0'; - buf[--read_len] = '\n'; - buf[--read_len] = '.'; - buf[--read_len] = '.'; - buf[--read_len] = '.'; - } - else { - buf[read_len] = '\0'; - } - printf("%s: %s", display_name, buf); - } - close(ffd); - } - if(event_count && --event_count == 0) - return 0; - event_size = sizeof(*event) + event->len; - res -= event_size; - event_pos += event_size; - } - } - - return 0; -} diff --git a/toolbox/powerd.c b/toolbox/powerd.c deleted file mode 100644 index 1f29a8b1257be797b6fcc06d7f00088f963a970d..0000000000000000000000000000000000000000 --- a/toolbox/powerd.c +++ /dev/null @@ -1,441 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <time.h> -#include <sys/select.h> -#include <sys/inotify.h> - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - -//#include <linux/input.h> // this does not compile - -// from <linux/input.h> - -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; - -#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ -#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ -#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ -#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ - -#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ -#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ -#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ - -#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */ -#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ -#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ -#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */ - -#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */ -#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */ -#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo) /* set abs value/limits */ - -#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */ -#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ -#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ - -#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ - -/* - * Event types - */ - -#define EV_SYN 0x00 -#define EV_KEY 0x01 -#define EV_REL 0x02 -#define EV_ABS 0x03 -#define EV_MSC 0x04 -#define EV_SW 0x05 -#define EV_LED 0x11 -#define EV_SND 0x12 -#define EV_REP 0x14 -#define EV_FF 0x15 -#define EV_PWR 0x16 -#define EV_FF_STATUS 0x17 -#define EV_MAX 0x1f - -#define KEY_POWER 116 -#define KEY_SLEEP 142 -#define SW_0 0x00 - -// end <linux/input.h> - -struct notify_entry { - int id; - int (*handler)(struct notify_entry *entry, struct inotify_event *event); - const char *filename; -}; - -int charging_state_notify_handler(struct notify_entry *entry, struct inotify_event *event) -{ - static int state = -1; - int last_state; - char buf[40]; - int read_len; - int fd; - - last_state = state; - fd = open(entry->filename, O_RDONLY); - read_len = read(fd, buf, sizeof(buf)); - if(read_len > 0) { - //printf("charging_state_notify_handler: \"%s\"\n", buf); - state = !(strncmp(buf, "Unknown", 7) == 0 - || strncmp(buf, "Discharging", 11) == 0); - } - close(fd); - //printf("charging_state_notify_handler: %d -> %d\n", last_state, state); - return state > last_state; -} - -struct notify_entry watched_files[] = { - { - .filename = "/sys/android_power/charging_state", - .handler = charging_state_notify_handler - } -}; - -int call_notify_handler(struct inotify_event *event) -{ - unsigned int start, i; - start = event->wd - watched_files[0].id; - if(start >= ARRAY_SIZE(watched_files)) - start = 0; - //printf("%d: %08x \"%s\"\n", event->wd, event->mask, event->len ? event->name : ""); - for(i = start; i < ARRAY_SIZE(watched_files); i++) { - if(event->wd == watched_files[i].id) { - if(watched_files[i].handler) { - return watched_files[i].handler(&watched_files[i], event); - } - return 1; - } - } - for(i = 0; i < start; i++) { - if(event->wd == watched_files[i].id) { - if(watched_files[i].handler) { - return watched_files[i].handler(&watched_files[i], event); - } - return 1; - } - } - return 0; -} - -int handle_inotify_event(int nfd) -{ - int res; - int wake_up = 0; - struct inotify_event *event; - char event_buf[512]; - int event_pos = 0; - - res = read(nfd, event_buf, sizeof(event_buf)); - if(res < (int)sizeof(*event)) { - if(errno == EINTR) - return 0; - fprintf(stderr, "could not get event, %s\n", strerror(errno)); - return 0; - } - printf("got %d bytes of event information\n", res); - while(res >= (int)sizeof(*event)) { - int event_size; - event = (struct inotify_event *)(event_buf + event_pos); - wake_up |= call_notify_handler(event); - event_size = sizeof(*event) + event->len; - res -= event_size; - event_pos += event_size; - } - return wake_up; -} - -int powerd_main(int argc, char *argv[]) -{ - int c; - unsigned int i; - int res; - struct timeval tv; - int eventfd; - int notifyfd; - int powerfd; - int powerfd_is_sleep; - int user_activity_fd; - int acquire_partial_wake_lock_fd; - int acquire_full_wake_lock_fd; - int release_wake_lock_fd; - char *eventdev = "/dev/input/event0"; - const char *android_sleepdev = "/sys/android_power/request_sleep"; - const char *android_autooff_dev = "/sys/android_power/auto_off_timeout"; - const char *android_user_activity_dev = "/sys/android_power/last_user_activity"; - const char *android_acquire_partial_wake_lock_dev = "/sys/android_power/acquire_partial_wake_lock"; - const char *android_acquire_full_wake_lock_dev = "/sys/android_power/acquire_full_wake_lock"; - const char *android_release_wake_lock_dev = "/sys/android_power/release_wake_lock"; - const char *powerdev = "/sys/power/state"; - const char suspendstring[] = "standby"; - const char wakelockstring[] = "powerd"; - fd_set rfds; - struct input_event event; - struct input_event light_event; - struct input_event light_event2; - int gotkey = 1; - time_t idle_time = 5; - const char *idle_time_string = "5"; - time_t lcd_light_time = 0; - time_t key_light_time = 0; - int verbose = 1; - int event_sleep = 0; - int got_power_key_down = 0; - struct timeval power_key_down_time = { 0, 0 }; - - light_event.type = EV_LED; - light_event.code = 4; // bright lcd backlight - light_event.value = 0; // light off -- sleep after timeout - - light_event2.type = EV_LED; - light_event2.code = 8; // keyboard backlight - light_event2.value = 0; // light off -- sleep after timeout - - do { - c = getopt(argc, argv, "e:ni:vql:k:"); - if (c == EOF) - break; - switch (c) { - case 'e': - eventdev = optarg; - break; - case 'n': - gotkey = 0; - break; - case 'i': - idle_time = atoi(optarg); - idle_time_string = optarg; - break; - case 'v': - verbose = 2; - break; - case 'q': - verbose = 0; - break; - case 'l': - lcd_light_time = atoi(optarg); - break; - case 'k': - key_light_time = atoi(optarg); - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - if(optind != argc) { - fprintf(stderr,"%s [-e eventdev]\n", argv[0]); - return 1; - } - - eventfd = open(eventdev, O_RDWR | O_NONBLOCK); - if(eventfd < 0) { - fprintf(stderr, "could not open %s, %s\n", eventdev, strerror(errno)); - return 1; - } - if(key_light_time >= lcd_light_time) { - lcd_light_time = key_light_time + 1; - fprintf(stderr,"lcd bright backlight time must be longer than keyboard backlight time.\n" - "Setting lcd bright backlight time to %ld seconds\n", lcd_light_time); - } - - user_activity_fd = open(android_user_activity_dev, O_RDWR); - if(user_activity_fd >= 0) { - int auto_off_fd = open(android_autooff_dev, O_RDWR); - write(auto_off_fd, idle_time_string, strlen(idle_time_string)); - close(auto_off_fd); - } - - powerfd = open(android_sleepdev, O_RDWR); - if(powerfd >= 0) { - powerfd_is_sleep = 1; - if(verbose > 0) - printf("Using android sleep dev: %s\n", android_sleepdev); - } - else { - powerfd_is_sleep = 0; - powerfd = open(powerdev, O_RDWR); - if(powerfd >= 0) { - if(verbose > 0) - printf("Using linux power dev: %s\n", powerdev); - } - } - if(powerfd < 0) { - fprintf(stderr, "could not open %s, %s\n", powerdev, strerror(errno)); - return 1; - } - - notifyfd = inotify_init(); - if(notifyfd < 0) { - fprintf(stderr, "inotify_init failed, %s\n", strerror(errno)); - return 1; - } - fcntl(notifyfd, F_SETFL, O_NONBLOCK | fcntl(notifyfd, F_GETFL)); - for(i = 0; i < ARRAY_SIZE(watched_files); i++) { - watched_files[i].id = inotify_add_watch(notifyfd, watched_files[i].filename, IN_MODIFY); - printf("Watching %s, id %d\n", watched_files[i].filename, watched_files[i].id); - } - - acquire_partial_wake_lock_fd = open(android_acquire_partial_wake_lock_dev, O_RDWR); - acquire_full_wake_lock_fd = open(android_acquire_full_wake_lock_dev, O_RDWR); - release_wake_lock_fd = open(android_release_wake_lock_dev, O_RDWR); - - if(user_activity_fd >= 0) { - idle_time = 60*60*24; // driver handles real timeout - } - if(gotkey) { - tv.tv_sec = idle_time; - tv.tv_usec = 0; - } - else { - tv.tv_sec = 0; - tv.tv_usec = 500000; - } - - while(1) { - FD_ZERO(&rfds); - //FD_SET(0, &rfds); - FD_SET(eventfd, &rfds); - FD_SET(notifyfd, &rfds); - res = select(((notifyfd > eventfd) ? notifyfd : eventfd) + 1, &rfds, NULL, NULL, &tv); - if(res < 0) { - fprintf(stderr, "select failed, %s\n", strerror(errno)); - return 1; - } - if(res == 0) { - if(light_event2.value == 1) - goto light2_off; - if(light_event.value == 1) - goto light_off; - if(user_activity_fd < 0) { - if(gotkey && verbose > 0) - printf("Idle - sleep\n"); - if(!gotkey && verbose > 1) - printf("Reenter sleep\n"); - goto sleep; - } - else { - tv.tv_sec = 60*60*24; - tv.tv_usec = 0; - } - } - if(res > 0) { - //if(FD_ISSET(0, &rfds)) { - // printf("goto data on stdin quit\n"); - // return 0; - //} - if(FD_ISSET(notifyfd, &rfds)) { - write(acquire_partial_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - if(handle_inotify_event(notifyfd) > 0) { - write(acquire_full_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - } - write(release_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - } - if(FD_ISSET(eventfd, &rfds)) { - write(acquire_partial_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - res = read(eventfd, &event, sizeof(event)); - if(res < (int)sizeof(event)) { - fprintf(stderr, "could not get event\n"); - write(release_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - return 1; - } - if(event.type == EV_PWR && event.code == KEY_SLEEP) { - event_sleep = event.value; - } - if(event.type == EV_KEY || (event.type == EV_SW && event.code == SW_0 && event.value == 1)) { - gotkey = 1; - if(user_activity_fd >= 0) { - char buf[32]; - int len; - len = sprintf(buf, "%ld%06lu000", event.time.tv_sec, event.time.tv_usec); - write(user_activity_fd, buf, len); - } - if(lcd_light_time | key_light_time) { - tv.tv_sec = key_light_time; - light_event.value = 1; - write(eventfd, &light_event, sizeof(light_event)); - light_event2.value = 1; - write(eventfd, &light_event2, sizeof(light_event2)); - } - else { - tv.tv_sec = idle_time; - } - tv.tv_usec = 0; - if(verbose > 1) - printf("got %s %s %d%s\n", event.type == EV_KEY ? "key" : "switch", event.value ? "down" : "up", event.code, event_sleep ? " from sleep" : ""); - if(event.code == KEY_POWER) { - if(event.value == 0) { - int tmp_got_power_key_down = got_power_key_down; - got_power_key_down = 0; - if(tmp_got_power_key_down) { - // power key released - if(verbose > 0) - printf("Power key released - sleep\n"); - write(release_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - goto sleep; - } - } - else if(event_sleep == 0) { - got_power_key_down = 1; - power_key_down_time = event.time; - } - } - } - if(event.type == EV_SW && event.code == SW_0 && event.value == 0) { - if(verbose > 0) - printf("Flip closed - sleep\n"); - power_key_down_time = event.time; - write(release_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - goto sleep; - } - write(release_wake_lock_fd, wakelockstring, sizeof(wakelockstring) - 1); - } - } - if(0) { -light_off: - light_event.value = 0; - write(eventfd, &light_event, sizeof(light_event)); - tv.tv_sec = idle_time - lcd_light_time; - } - if(0) { -light2_off: - light_event2.value = 0; - write(eventfd, &light_event2, sizeof(light_event2)); - tv.tv_sec = lcd_light_time - key_light_time; - } - if(0) { -sleep: - if(light_event.value == 1) { - light_event.value = 0; - write(eventfd, &light_event, sizeof(light_event)); - light_event2.value = 0; - write(eventfd, &light_event2, sizeof(light_event2)); - tv.tv_sec = idle_time - lcd_light_time; - } - if(powerfd_is_sleep) { - char buf[32]; - int len; - len = sprintf(buf, "%ld%06lu000", power_key_down_time.tv_sec, power_key_down_time.tv_usec); - write(powerfd, buf, len); - } - else - write(powerfd, suspendstring, sizeof(suspendstring) - 1); - gotkey = 0; - tv.tv_sec = 0; - tv.tv_usec = 500000; - } - } - - return 0; -} diff --git a/toolbox/printenv.c b/toolbox/printenv.c deleted file mode 100644 index d5ea5313c7b96e222fa7bb1e7683b2cdd98d7508..0000000000000000000000000000000000000000 --- a/toolbox/printenv.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> - -extern char** environ; - -int printenv_main (int argc, char **argv) -{ - char** e; - char* v; - int i; - - if (argc == 1) { - e = environ; - while (*e) { - printf("%s\n", *e); - e++; - } - } else { - for (i=1; i<argc; i++) { - v = getenv(argv[i]); - if (v) { - printf("%s\n", v); - } - } - } - - return 0; -} - diff --git a/toolbox/ps.c b/toolbox/ps.c deleted file mode 100644 index 3b86fa252b18436d1b58b9ecc91dc1fcd7a4d752..0000000000000000000000000000000000000000 --- a/toolbox/ps.c +++ /dev/null @@ -1,214 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <fcntl.h> - -#include <string.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> - -#include <pwd.h> - - -static char *nexttoksep(char **strp, char *sep) -{ - char *p = strsep(strp,sep); - return (p == 0) ? "" : p; -} -static char *nexttok(char **strp) -{ - return nexttoksep(strp, " "); -} - -#define SHOW_PRIO 1 -#define SHOW_TIME 2 - -static int display_flags = 0; - -static int ps_line(int pid, int tid, char *namefilter) -{ - char statline[1024]; - char cmdline[1024]; - char user[32]; - struct stat stats; - int fd, r; - char *ptr, *name, *state; - int ppid, tty; - unsigned wchan, rss, vss, eip; - unsigned utime, stime; - int prio, nice, rtprio, sched; - struct passwd *pw; - - sprintf(statline, "/proc/%d", pid); - stat(statline, &stats); - - if(tid) { - sprintf(statline, "/proc/%d/task/%d/stat", pid, tid); - cmdline[0] = 0; - } else { - sprintf(statline, "/proc/%d/stat", pid); - sprintf(cmdline, "/proc/%d/cmdline", pid); - fd = open(cmdline, O_RDONLY); - if(fd == 0) { - r = 0; - } else { - r = read(fd, cmdline, 1023); - close(fd); - if(r < 0) r = 0; - } - cmdline[r] = 0; - } - - fd = open(statline, O_RDONLY); - if(fd == 0) return -1; - r = read(fd, statline, 1023); - close(fd); - if(r < 0) return -1; - statline[r] = 0; - - ptr = statline; - nexttok(&ptr); // skip pid - ptr++; // skip "(" - - name = ptr; - ptr = strrchr(ptr, ')'); // Skip to *last* occurence of ')', - *ptr++ = '\0'; // and null-terminate name. - - ptr++; // skip " " - state = nexttok(&ptr); - ppid = atoi(nexttok(&ptr)); - nexttok(&ptr); // pgrp - nexttok(&ptr); // sid - tty = atoi(nexttok(&ptr)); - - nexttok(&ptr); // tpgid - nexttok(&ptr); // flags - nexttok(&ptr); // minflt - nexttok(&ptr); // cminflt - nexttok(&ptr); // majflt - nexttok(&ptr); // cmajflt -#if 1 - utime = atoi(nexttok(&ptr)); - stime = atoi(nexttok(&ptr)); -#else - nexttok(&ptr); // utime - nexttok(&ptr); // stime -#endif - nexttok(&ptr); // cutime - nexttok(&ptr); // cstime - prio = atoi(nexttok(&ptr)); - nice = atoi(nexttok(&ptr)); - nexttok(&ptr); // threads - nexttok(&ptr); // itrealvalue - nexttok(&ptr); // starttime - vss = strtoul(nexttok(&ptr), 0, 10); // vsize - rss = strtoul(nexttok(&ptr), 0, 10); // rss - nexttok(&ptr); // rlim - nexttok(&ptr); // startcode - nexttok(&ptr); // endcode - nexttok(&ptr); // startstack - nexttok(&ptr); // kstkesp - eip = strtoul(nexttok(&ptr), 0, 10); // kstkeip - nexttok(&ptr); // signal - nexttok(&ptr); // blocked - nexttok(&ptr); // sigignore - nexttok(&ptr); // sigcatch - wchan = strtoul(nexttok(&ptr), 0, 10); // wchan - nexttok(&ptr); // nswap - nexttok(&ptr); // cnswap - nexttok(&ptr); // exit signal - nexttok(&ptr); // processor - rtprio = atoi(nexttok(&ptr)); // rt_priority - sched = atoi(nexttok(&ptr)); // scheduling policy - - tty = atoi(nexttok(&ptr)); - - if(tid != 0) { - ppid = pid; - pid = tid; - } - - pw = getpwuid(stats.st_uid); - if(pw == 0) { - sprintf(user,"%d",(int)stats.st_uid); - } else { - strcpy(user,pw->pw_name); - } - - if(!namefilter || !strncmp(name, namefilter, strlen(namefilter))) { - printf("%-8s %-5d %-5d %-5d %-5d", user, pid, ppid, vss / 1024, rss * 4); - if(display_flags&SHOW_PRIO) - printf(" %-5d %-5d %-5d %-5d", prio, nice, rtprio, sched); - printf(" %08x %08x %s %s", wchan, eip, state, cmdline[0] ? cmdline : name); - if(display_flags&SHOW_TIME) - printf(" (u:%d, s:%d)", utime, stime); - printf("\n"); - } - return 0; -} - - -void ps_threads(int pid, char *namefilter) -{ - char tmp[128]; - DIR *d; - struct dirent *de; - - sprintf(tmp,"/proc/%d/task",pid); - d = opendir(tmp); - if(d == 0) return; - - while((de = readdir(d)) != 0){ - if(isdigit(de->d_name[0])){ - int tid = atoi(de->d_name); - if(tid == pid) continue; - ps_line(pid, tid, namefilter); - } - } - closedir(d); -} - -int ps_main(int argc, char **argv) -{ - DIR *d; - struct dirent *de; - char *namefilter = 0; - int pidfilter = 0; - int threads = 0; - - d = opendir("/proc"); - if(d == 0) return -1; - - while(argc > 1){ - if(!strcmp(argv[1],"-t")) { - threads = 1; - } else if(!strcmp(argv[1],"-x")) { - display_flags |= SHOW_TIME; - } else if(!strcmp(argv[1],"-p")) { - display_flags |= SHOW_PRIO; - } else if(isdigit(argv[1][0])){ - pidfilter = atoi(argv[1]); - } else { - namefilter = argv[1]; - } - argc--; - argv++; - } - - printf("USER PID PPID VSIZE RSS %sWCHAN PC NAME\n", - (display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":""); - while((de = readdir(d)) != 0){ - if(isdigit(de->d_name[0])){ - int pid = atoi(de->d_name); - if(!pidfilter || (pidfilter == pid)) { - ps_line(pid, 0, namefilter); - if(threads) ps_threads(pid, namefilter); - } - } - } - closedir(d); - return 0; -} - diff --git a/toolbox/r.c b/toolbox/r.c deleted file mode 100644 index 5a82e20c43325b7c75db9b3c61206a6b712ff911..0000000000000000000000000000000000000000 --- a/toolbox/r.c +++ /dev/null @@ -1,74 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <string.h> - -static int usage() -{ - fprintf(stderr,"r [-b|-s] <address> [<value>]\n"); - return -1; -} - -int r_main(int argc, char *argv[]) -{ - int width = 4, set = 0, fd; - unsigned addr, value; - void *page; - - if(argc < 2) return usage(); - - if(!strcmp(argv[1], "-b")) { - width = 1; - argc--; - argv++; - } else if(!strcmp(argv[1], "-s")) { - width = 2; - argc--; - argv++; - } - - if(argc < 2) return usage(); - addr = strtoul(argv[1], 0, 16); - - if(argc > 2) { - set = 1; - value = strtoul(argv[2], 0, 16); - } - - fd = open("/dev/mem", O_RDWR | O_SYNC); - if(fd < 0) { - fprintf(stderr,"cannot open /dev/mem\n"); - return -1; - } - - page = mmap(0, 8192, PROT_READ | PROT_WRITE, - MAP_SHARED, fd, addr & (~4095)); - - if(page == MAP_FAILED){ - fprintf(stderr,"cannot mmap region\n"); - return -1; - } - - switch(width){ - case 4: { - unsigned *x = (unsigned*) (((unsigned) page) + (addr & 4095)); - if(set) *x = value; - fprintf(stderr,"%08x: %08x\n", addr, *x); - break; - } - case 2: { - unsigned short *x = (unsigned short*) (((unsigned) page) + (addr & 4095)); - if(set) *x = value; - fprintf(stderr,"%08x: %04x\n", addr, *x); - break; - } - case 1: { - unsigned char *x = (unsigned char*) (((unsigned) page) + (addr & 4095)); - if(set) *x = value; - fprintf(stderr,"%08x: %02x\n", addr, *x); - break; - } - } - return 0; -} diff --git a/toolbox/readtty.c b/toolbox/readtty.c deleted file mode 100644 index 2b275482665ce044305e60088c639d4db7fbcc42..0000000000000000000000000000000000000000 --- a/toolbox/readtty.c +++ /dev/null @@ -1,183 +0,0 @@ -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <string.h> -#include <termios.h> -#include <unistd.h> - -struct { - char key; - char *chars; -} map[] = { - { '1', "_ -1?!,.:;\"'<=>()_" }, - { '2', "Cabc2ABC" }, - { '3', "Fdef3DEF" }, - { '4', "Ighi4GHI" }, - { '5', "Ljkl5JKL" }, - { '6', "Omno6MNO" }, - { '7', "Spqrs7PQRS" }, - { '8', "Vtuv8TUV" }, - { '9', "Zwxyz9WXYZ" }, - { '0', "*+&0@/#*" }, -}; - -char next_char(char key, char current) -{ - int i; - char *next; - for(i = 0; i < sizeof(map) / sizeof(map[0]); i++) { - if(key == map[i].key) { - next = strchr(map[i].chars, current); - if(next && next[1]) - return next[1]; - return map[i].chars[1]; - } - } - return key; -} - -char prev_char(char key, char current) -{ - int i; - char *next; - for(i = 0; i < sizeof(map) / sizeof(map[0]); i++) { - if(key == map[i].key) { - next = strchr(map[i].chars+1, current); - if(next && next[-1]) - return next[-1]; - return map[i].chars[1]; - } - } - return key; -} - -int readtty_main(int argc, char *argv[]) -{ - int c; - //int flags; - char buf[1]; - int res; - struct termios ttyarg; - struct termios savedttyarg; - int nonblock = 0; - int timeout = 0; - int flush = 0; - int phone = 0; - char *accept = NULL; - char *rejectstring = NULL; - char last_char_in = 0; - char current_char = 0; - char *exit_string = NULL; - int exit_match = 0; - - do { - c = getopt(argc, argv, "nt:fa:r:pe:"); - if (c == EOF) - break; - switch (c) { - case 't': - timeout = atoi(optarg); - break; - case 'n': - nonblock = 1; - break; - case 'f': - flush = 1; - break; - case 'a': - accept = optarg; - break; - case 'r': - rejectstring = optarg; - break; - case 'p': - phone = 1; - break; - case 'e': - exit_string = optarg; - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if(flush) - tcflush(STDIN_FILENO, TCIFLUSH); - ioctl(STDIN_FILENO, TCGETS , &savedttyarg) ; /* set changed tty arguments */ - ttyarg = savedttyarg; - ttyarg.c_cc[VMIN] = (timeout > 0 || nonblock) ? 0 : 1; /* minimum of 0 chars */ - ttyarg.c_cc[VTIME] = timeout; /* wait max 15/10 sec */ - ttyarg.c_iflag = BRKINT | ICRNL; - ttyarg.c_lflag &= ~(ECHO | ICANON); - ioctl(STDIN_FILENO, TCSETS , &ttyarg); - - while (1) { - res = read(STDIN_FILENO, buf, 1); - if(res <= 0) { - if(phone) { - if(current_char) { - write(STDERR_FILENO, ¤t_char, 1); - write(STDOUT_FILENO, ¤t_char, 1); - if(exit_string && current_char == exit_string[exit_match]) { - exit_match++; - if(exit_string[exit_match] == '\0') - break; - } - else - exit_match = 0; - current_char = 0; - } - continue; - } - break; - } - if(accept && strchr(accept, buf[0]) == NULL) { - if(rejectstring) { - write(STDOUT_FILENO, rejectstring, strlen(rejectstring)); - break; - } - if(flush) - tcflush(STDIN_FILENO, TCIFLUSH); - continue; - } - if(phone) { - //if(!isprint(buf[0])) { - // fprintf(stderr, "got unprintable character 0x%x\n", buf[0]); - //} - if(buf[0] == '\0') { - if(current_char) { - current_char = prev_char(last_char_in, current_char); - write(STDERR_FILENO, ¤t_char, 1); - write(STDERR_FILENO, "\b", 1); - } - continue; - } - if(current_char && buf[0] != last_char_in) { - write(STDERR_FILENO, ¤t_char, 1); - write(STDOUT_FILENO, ¤t_char, 1); - if(exit_string && current_char == exit_string[exit_match]) { - exit_match++; - if(exit_string[exit_match] == '\0') - break; - } - else - exit_match = 0; - current_char = 0; - } - last_char_in = buf[0]; - current_char = next_char(last_char_in, current_char); - write(STDERR_FILENO, ¤t_char, 1); - write(STDERR_FILENO, "\b", 1); - continue; - } - write(STDOUT_FILENO, buf, 1); - break; - } - ioctl(STDIN_FILENO, TCSETS , &savedttyarg) ; /* set changed tty arguments */ - - return 0; -} diff --git a/toolbox/reboot.c b/toolbox/reboot.c deleted file mode 100644 index aebe18501fda2c8130f4a5602761658a10cedc88..0000000000000000000000000000000000000000 --- a/toolbox/reboot.c +++ /dev/null @@ -1,56 +0,0 @@ -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/reboot.h> -#include <unistd.h> - -int reboot_main(int argc, char *argv[]) -{ - int ret; - int nosync = 0; - int poweroff = 0; - - opterr = 0; - do { - int c; - - c = getopt(argc, argv, "np"); - - if (c == EOF) { - break; - } - - switch (c) { - case 'n': - nosync = 1; - break; - case 'p': - poweroff = 1; - break; - case '?': - fprintf(stderr, "usage: %s [-n] [-p] [rebootcommand]\n", argv[0]); - exit(EXIT_FAILURE); - } - } while (1); - - if(argc > optind + 1) { - fprintf(stderr, "%s: too many arguments\n", argv[0]); - exit(EXIT_FAILURE); - } - - if(!nosync) - sync(); - - if(poweroff) - ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_POWER_OFF, NULL); - else if(argc > optind) - ret = __reboot(LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, argv[optind]); - else - ret = reboot(RB_AUTOBOOT); - if(ret < 0) { - perror("reboot"); - exit(EXIT_FAILURE); - } - fprintf(stderr, "reboot returned\n"); - return 0; -} diff --git a/toolbox/renice.c b/toolbox/renice.c deleted file mode 100644 index 978b3295c6b18dfb53399411107ed0ec789e869f..0000000000000000000000000000000000000000 --- a/toolbox/renice.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> -#include <sys/time.h> -#include <sys/resource.h> -#include <sched.h> - -static void -usage(const char *s) -{ - fprintf(stderr, "USAGE: %s [[-r] priority pids ...] [-g pid]\n", s); - exit(EXIT_FAILURE); -} - -void print_prio(pid_t pid) -{ - int sched; - struct sched_param sp; - - printf("pid %d's priority: %d\n", pid, getpriority(PRIO_PROCESS, pid)); - - printf("scheduling class: "); - sched = sched_getscheduler(pid); - switch (sched) { - case SCHED_FIFO: - printf("FIFO\n"); - break; - case SCHED_RR: - printf("RR\n"); - break; - case SCHED_OTHER: - printf("Normal\n"); - break; - case -1: - perror("sched_getscheduler"); - break; - default: - printf("Unknown\n"); - } - - sched_getparam(pid, &sp); - printf("RT prio: %d (of %d to %d)\n", sp.sched_priority, - sched_get_priority_min(sched), sched_get_priority_max(sched)); -} - -int renice_main(int argc, char *argv[]) -{ - int prio; - int realtime = 0; - char *cmd = argv[0]; - - // consume command name - argc--; - argv++; - - if (argc < 1) - usage(cmd); - - if(strcmp("-r", argv[0]) == 0) { - // do realtime priority adjustment - realtime = 1; - argc--; - argv++; - } - - if(strcmp("-g", argv[0]) == 0) { - if (argc < 2) - usage(cmd); - print_prio(atoi(argv[1])); - return 0; - } - - if (argc < 1) - usage(cmd); - - prio = atoi(argv[0]); - argc--; - argv++; - - if (argc < 1) - usage(cmd); - - while(argc) { - pid_t pid; - - pid = atoi(argv[0]); - argc--; - argv++; - - if (realtime) { - struct sched_param sp = { .sched_priority = prio }; - int ret; - - ret = sched_setscheduler(pid, SCHED_RR, &sp); - if (ret) { - perror("sched_set_scheduler"); - exit(EXIT_FAILURE); - } - } else { - int ret; - - ret = setpriority(PRIO_PROCESS, pid, prio); - if (ret) { - perror("setpriority"); - exit(EXIT_FAILURE); - } - } - } - - return 0; -} - - diff --git a/toolbox/rm.c b/toolbox/rm.c deleted file mode 100644 index bd66311814d00aea877d1b43d6f255b2565a3bc6..0000000000000000000000000000000000000000 --- a/toolbox/rm.c +++ /dev/null @@ -1,92 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/types.h> - -static int usage() -{ - fprintf(stderr,"rm [-rR] <target>\n"); - return -1; -} - -/* return -1 on failure, with errno set to the first error */ -static int unlink_recursive(const char* name) -{ - struct stat st; - DIR *dir; - struct dirent *de; - int fail = 0; - - /* is it a file or directory? */ - if (lstat(name, &st) < 0) - return -1; - - /* a file, so unlink it */ - if (!S_ISDIR(st.st_mode)) - return unlink(name); - - /* a directory, so open handle */ - dir = opendir(name); - if (dir == NULL) - return -1; - - /* recurse over components */ - errno = 0; - while ((de = readdir(dir)) != NULL) { - char dn[PATH_MAX]; - if (!strcmp(de->d_name, "..") || !strcmp(de->d_name, ".")) - continue; - sprintf(dn, "%s/%s", name, de->d_name); - if (unlink_recursive(dn) < 0) { - fail = 1; - break; - } - errno = 0; - } - /* in case readdir or unlink_recursive failed */ - if (fail || errno < 0) { - int save = errno; - closedir(dir); - errno = save; - return -1; - } - - /* close directory handle */ - if (closedir(dir) < 0) - return -1; - - /* delete target directory */ - return rmdir(name); -} - -int rm_main(int argc, char *argv[]) -{ - int ret; - int i = 1; - int recursive = 0; - - if (argc < 2) - return usage(); - - /* check if recursive */ - if (argc >=2 && (!strcmp(argv[1], "-r") || !strcmp(argv[1], "-R"))) { - recursive = 1; - i = 2; - } - - /* loop over the file/directory args */ - for (; i < argc; i++) { - int ret = recursive ? unlink_recursive(argv[i]) : unlink(argv[i]); - if (ret < 0) { - fprintf(stderr, "rm failed for %s, %s\n", argv[i], strerror(errno)); - return -1; - } - } - - return 0; -} - diff --git a/toolbox/rmdir.c b/toolbox/rmdir.c deleted file mode 100644 index 06f3df26cf247f4f9ee91be1c5f9d51c8b2e8227..0000000000000000000000000000000000000000 --- a/toolbox/rmdir.c +++ /dev/null @@ -1,29 +0,0 @@ -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <errno.h> - -static int usage() -{ - fprintf(stderr,"rmdir <directory>\n"); - return -1; -} - -int rmdir_main(int argc, char *argv[]) -{ - int symbolic = 0; - int ret; - if(argc < 2) return usage(); - - while(argc > 1) { - argc--; - argv++; - ret = rmdir(argv[0]); - if(ret < 0) { - fprintf(stderr, "rmdir failed for %s, %s\n", argv[0], strerror(errno)); - return ret; - } - } - - return 0; -} diff --git a/toolbox/rmmod.c b/toolbox/rmmod.c deleted file mode 100644 index 7e10c061b70c68de601ccece10a663ce88bc88fc..0000000000000000000000000000000000000000 --- a/toolbox/rmmod.c +++ /dev/null @@ -1,42 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <malloc.h> -#include <errno.h> -#include <asm/unistd.h> - -extern int delete_module(const char *, unsigned int); - -int rmmod_main(int argc, char **argv) -{ - int ret; - char *modname, *dot; - - /* make sure we've got an argument */ - if (argc < 2) { - fprintf(stderr, "usage: rmmod <module>\n"); - return -1; - } - - /* if given /foo/bar/blah.ko, make a weak attempt - * to convert to "blah", just for convenience - */ - modname = strrchr(argv[1], '/'); - if (!modname) - modname = argv[1]; - dot = strchr(argv[1], '.'); - if (dot) - *dot = '\0'; - - /* pass it to the kernel */ - ret = delete_module(modname, O_NONBLOCK | O_EXCL); - if (ret != 0) { - fprintf(stderr, "rmmod: delete_module '%s' failed (errno %d)\n", - modname, errno); - return -1; - } - - return 0; -} - diff --git a/toolbox/rotatefb.c b/toolbox/rotatefb.c deleted file mode 100644 index 2ff41278c5b398c07caf62c876b5163af7ddf93e..0000000000000000000000000000000000000000 --- a/toolbox/rotatefb.c +++ /dev/null @@ -1,71 +0,0 @@ -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/mman.h> -#include <fcntl.h> -#include <string.h> -#include <termios.h> -#include <unistd.h> -#include <errno.h> -#include <linux/fb.h> - - -int rotatefb_main(int argc, char *argv[]) -{ - int c; - char *fbdev = "/dev/graphics/fb0"; - int rotation = 0; - int fd; - int res; - struct fb_var_screeninfo fbinfo; - - do { - c = getopt(argc, argv, "d:"); - if (c == EOF) - break; - switch (c) { - case 'd': - fbdev = optarg; - break; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - - if(optind + 1 != argc) { - fprintf(stderr, "%s: specify rotation\n", argv[0]); - exit(1); - } - rotation = atoi(argv[optind]); - - fd = open(fbdev, O_RDWR); - if(fd < 0) { - fprintf(stderr, "cannot open %s\n", fbdev); - return 1; - } - - res = ioctl(fd, FBIOGET_VSCREENINFO, &fbinfo); - if(res < 0) { - fprintf(stderr, "failed to get fbinfo: %s\n", strerror(errno)); - return 1; - } - if((fbinfo.rotate ^ rotation) & 1) { - unsigned int xres = fbinfo.yres; - fbinfo.yres = fbinfo.xres; - fbinfo.xres = xres; - fbinfo.xres_virtual = fbinfo.xres; - fbinfo.yres_virtual = fbinfo.yres * 2; - if(fbinfo.yoffset == xres) - fbinfo.yoffset = fbinfo.yres; - } - fbinfo.rotate = rotation; - res = ioctl(fd, FBIOPUT_VSCREENINFO, &fbinfo); - if(res < 0) { - fprintf(stderr, "failed to set fbinfo: %s\n", strerror(errno)); - return 1; - } - - return 0; -} diff --git a/toolbox/route.c b/toolbox/route.c deleted file mode 100644 index adf5c696a58512526a7df7c0073084d025d27596..0000000000000000000000000000000000000000 --- a/toolbox/route.c +++ /dev/null @@ -1,97 +0,0 @@ - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#include <errno.h> -#include <string.h> -#include <ctype.h> - -#include <sys/socket.h> -#include <netinet/in.h> -#include <linux/if.h> -#include <linux/sockios.h> -#include <arpa/inet.h> -#include <linux/route.h> - -static void die(const char *s) -{ - fprintf(stderr,"error: %s (%s)\n", s, strerror(errno)); - exit(-1); -} - -static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr) -{ - sin->sin_family = AF_INET; - sin->sin_port = 0; - sin->sin_addr.s_addr = inet_addr(addr); -} - -#define ADVANCE(argc, argv) do { argc--, argv++; } while(0) -#define EXPECT_NEXT(argc, argv) do { \ - ADVANCE(argc, argv); \ - if (0 == argc) { \ - errno = EINVAL; \ - die("expecting one more argument"); \ - } \ -} while(0) - -/* current support two kinds of usage */ -/* route add default dev wlan0 */ -/* route add default gw 192.168.20.1 dev wlan0 */ - -int route_main(int argc, char *argv[]) -{ - struct ifreq ifr; - int s,i; - struct rtentry rt; - struct sockaddr_in ina; - - if(argc == 0) return 0; - - strncpy(ifr.ifr_name, argv[0], IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = 0; - ADVANCE(argc, argv); - - if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - die("cannot open control socket\n"); - } - - while(argc > 0){ - if(!strcmp(argv[0], "add")) { - EXPECT_NEXT(argc, argv); - if(!strcmp(argv[0], "default")) { - EXPECT_NEXT(argc, argv); - memset((char *) &rt, 0, sizeof(struct rtentry)); - rt.rt_dst.sa_family = AF_INET; - if(!strcmp(argv[0], "dev")) { - EXPECT_NEXT(argc, argv); - rt.rt_flags = RTF_UP | RTF_HOST; - rt.rt_dev = argv[0]; - if (ioctl(s, SIOCADDRT, &rt) < 0) die("SIOCADDRT"); - }else if(!strcmp(argv[0], "gw")) { - EXPECT_NEXT(argc, argv); - rt.rt_flags = RTF_UP | RTF_GATEWAY; - init_sockaddr_in((struct sockaddr_in *)&(rt.rt_genmask), "0.0.0.0"); - if(isdigit(argv[0][0])){ - init_sockaddr_in((struct sockaddr_in *)&(rt.rt_gateway), argv[0]); - }else{ - die("expecting an IP address for parameter \"gw\""); - } - EXPECT_NEXT(argc, argv); - if(!strcmp(argv[0], "dev")) { - EXPECT_NEXT(argc, argv); - rt.rt_dev = argv[0]; - if (ioctl(s, SIOCADDRT, &rt) < 0){ - die("SIOCADDRT"); - } - } - } - } - } - ADVANCE(argc, argv); - } - - return 0; -} - diff --git a/toolbox/schedtop.c b/toolbox/schedtop.c deleted file mode 100644 index c0e01412dec51460be229c8165dc59b6874d76eb..0000000000000000000000000000000000000000 --- a/toolbox/schedtop.c +++ /dev/null @@ -1,335 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <ctype.h> -#include <fcntl.h> - -#include <string.h> - -#include <sys/stat.h> -#include <sys/types.h> -#include <dirent.h> -#include <signal.h> - -#include <pwd.h> - -struct thread_info { - int pid; - int tid; - char name[64]; - uint64_t exec_time; - uint64_t delay_time; - uint32_t run_count; -}; - -struct thread_table { - size_t allocated; - size_t active; - struct thread_info *data; -}; - -enum { - FLAG_BATCH = 1U << 0, - FLAG_HIDE_IDLE = 1U << 1, - FLAG_SHOW_THREADS = 1U << 2, - FLAG_USE_ALTERNATE_SCREEN = 1U << 3, -}; - -static int time_dp = 9; -static int time_div = 1; -#define NS_TO_S_D(ns) \ - (uint32_t)((ns) / 1000000000), time_dp, ((uint32_t)((ns) % 1000000000) / time_div) - -struct thread_table processes; -struct thread_table last_processes; -struct thread_table threads; -struct thread_table last_threads; - -static void grow_table(struct thread_table *table) -{ - size_t size = table->allocated; - struct thread_info *new_table; - if (size < 128) - size = 128; - else - size *= 2; - - new_table = realloc(table->data, size * sizeof(*table->data)); - if (new_table == NULL) { - fprintf(stderr, "out of memory\n"); - exit(1); - } - table->data = new_table; - table->allocated = size; -} - -static struct thread_info *get_item(struct thread_table *table) -{ - if (table->active >= table->allocated) - grow_table(table); - return table->data + table->active; -} - -static void commit_item(struct thread_table *table) -{ - table->active++; -} - -static int read_line(char *line, size_t line_size) -{ - int fd; - int len; - fd = open(line, O_RDONLY); - if(fd == 0) - return -1; - len = read(fd, line, line_size - 1); - close(fd); - if (len <= 0) - return -1; - line[len] = '\0'; - return 0; -} - -static void add_thread(int pid, int tid, struct thread_info *proc_info) -{ - char line[1024]; - char *name, *name_end; - size_t name_len; - struct thread_info *info; - if(tid == 0) - info = get_item(&processes); - else - info = get_item(&threads); - info->pid = pid; - info->tid = tid; - - if(tid) - sprintf(line, "/proc/%d/task/%d/schedstat", pid, tid); - else - sprintf(line, "/proc/%d/schedstat", pid); - if (read_line(line, sizeof(line))) - return; - if(sscanf(line, "%llu %llu %u", &info->exec_time, &info->delay_time, &info->run_count) != 3) - return; - if (proc_info) { - proc_info->exec_time += info->exec_time; - proc_info->delay_time += info->delay_time; - proc_info->run_count += info->run_count; - } - - name = NULL; - if (!tid) { - sprintf(line, "/proc/%d/cmdline", pid); - if (read_line(line, sizeof(line)) == 0 && line[0]) { - name = line; - name_len = strlen(name); - } - } - if (!name) { - if (tid) - sprintf(line, "/proc/%d/task/%d/stat", pid, tid); - else - sprintf(line, "/proc/%d/stat", pid); - if (read_line(line, sizeof(line))) - return; - name = strchr(line, '('); - if (name == NULL) - return; - name_end = strchr(name, ')'); - if (name_end == NULL) - return; - name++; - name_len = name_end - name; - } - if (name_len >= sizeof(info->name)) - name_len = sizeof(info->name) - 1; - memcpy(info->name, name, name_len); - info->name[name_len] = '\0'; - if(tid == 0) - commit_item(&processes); - else - commit_item(&threads); -} - -static void add_threads(int pid, struct thread_info *proc_info) -{ - char path[1024]; - DIR *d; - struct dirent *de; - sprintf(path, "/proc/%d/task", pid); - d = opendir(path); - if(d == 0) return; - while((de = readdir(d)) != 0){ - if(isdigit(de->d_name[0])){ - int tid = atoi(de->d_name); - add_thread(pid, tid, proc_info); - } - } - closedir(d); -} - -static void print_threads(int pid, uint32_t flags) -{ - size_t i, j; - for (i = 0; i < last_threads.active; i++) { - int epid = last_threads.data[i].pid; - int tid = last_threads.data[i].tid; - if (epid != pid) - continue; - for (j = 0; j < threads.active; j++) - if (tid == threads.data[j].tid) - break; - if (j == threads.active) - printf(" %5u died\n", tid); - else if (!(flags & FLAG_HIDE_IDLE) || threads.data[j].run_count - last_threads.data[i].run_count) - printf(" %5u %2u.%0*u %2u.%0*u %5u %5u.%0*u %5u.%0*u %7u %s\n", tid, - NS_TO_S_D(threads.data[j].exec_time - last_threads.data[i].exec_time), - NS_TO_S_D(threads.data[j].delay_time - last_threads.data[i].delay_time), - threads.data[j].run_count - last_threads.data[i].run_count, - NS_TO_S_D(threads.data[j].exec_time), NS_TO_S_D(threads.data[j].delay_time), - threads.data[j].run_count, threads.data[j].name); - } -} - -static void update_table(DIR *d, uint32_t flags) -{ - size_t i, j; - struct dirent *de; - - rewinddir(d); - while((de = readdir(d)) != 0){ - if(isdigit(de->d_name[0])){ - int pid = atoi(de->d_name); - struct thread_info *proc_info; - add_thread(pid, 0, NULL); - proc_info = &processes.data[processes.active - 1]; - proc_info->exec_time = 0; - proc_info->delay_time = 0; - proc_info->run_count = 0; - add_threads(pid, proc_info); - } - } - if (!(flags & FLAG_BATCH)) - printf("\e[H\e[0J"); - printf("Processes: %d, Threads %d\n", processes.active, threads.active); - switch (time_dp) { - case 3: - printf(" TID --- SINCE LAST ---- ---------- TOTAL ----------\n"); - printf(" PID EXEC_T DELAY SCHED EXEC_TIME DELAY_TIM SCHED NAME\n"); - break; - case 6: - printf(" TID ------ SINCE LAST ------- ------------ TOTAL -----------\n"); - printf(" PID EXEC_TIME DELAY_TIM SCHED EXEC_TIME DELAY_TIME SCHED NAME\n"); - break; - default: - printf(" TID -------- SINCE LAST -------- ------------- TOTAL -------------\n"); - printf(" PID EXEC_TIME DELAY_TIME SCHED EXEC_TIME DELAY_TIME SCHED NAME\n"); - break; - } - for (i = 0; i < last_processes.active; i++) { - int pid = last_processes.data[i].pid; - int tid = last_processes.data[i].tid; - for (j = 0; j < processes.active; j++) - if (pid == processes.data[j].pid) - break; - if (j == processes.active) - printf("%5u died\n", pid); - else if (!(flags & FLAG_HIDE_IDLE) || processes.data[j].run_count - last_processes.data[i].run_count) { - printf("%5u %2u.%0*u %2u.%0*u %5u %5u.%0*u %5u.%0*u %7u %s\n", pid, - NS_TO_S_D(processes.data[j].exec_time - last_processes.data[i].exec_time), - NS_TO_S_D(processes.data[j].delay_time - last_processes.data[i].delay_time), - processes.data[j].run_count - last_processes.data[i].run_count, - NS_TO_S_D(processes.data[j].exec_time), NS_TO_S_D(processes.data[j].delay_time), - processes.data[j].run_count, processes.data[j].name); - if (flags & FLAG_SHOW_THREADS) - print_threads(pid, flags); - } - } - - { - struct thread_table tmp; - tmp = last_processes; - last_processes = processes; - processes = tmp; - processes.active = 0; - tmp = last_threads; - last_threads = threads; - threads = tmp; - threads.active = 0; - } -} - -void -sig_abort(int signum) -{ - printf("\e[?47l"); - exit(0); -} - - -int schedtop_main(int argc, char **argv) -{ - int c; - DIR *d; - struct dirent *de; - char *namefilter = 0; - int pidfilter = 0; - uint32_t flags = 0; - int delay = 3000000; - float delay_f; - - while(1) { - c = getopt(argc, argv, "d:ibtamun"); - if (c == EOF) - break; - switch (c) { - case 'd': - delay_f = atof(optarg); - delay = delay_f * 1000000; - break; - case 'b': - flags |= FLAG_BATCH; - break; - case 'i': - flags |= FLAG_HIDE_IDLE; - break; - case 't': - flags |= FLAG_SHOW_THREADS; - break; - case 'a': - flags |= FLAG_USE_ALTERNATE_SCREEN; - break; - case 'm': - time_dp = 3; - time_div = 1000000; - break; - case 'u': - time_dp = 6; - time_div = 1000; - break; - case 'n': - time_dp = 9; - time_div = 1; - break; - } - } - - d = opendir("/proc"); - if(d == 0) return -1; - - if (!(flags & FLAG_BATCH)) { - if(flags & FLAG_USE_ALTERNATE_SCREEN) { - signal(SIGINT, sig_abort); - signal(SIGPIPE, sig_abort); - signal(SIGTERM, sig_abort); - printf("\e7\e[?47h"); - } - printf("\e[2J"); - } - while (1) { - update_table(d, flags); - usleep(delay); - } - closedir(d); - return 0; -} - diff --git a/toolbox/sendevent.c b/toolbox/sendevent.c deleted file mode 100644 index 1608e6c777e0f06f729c44ec04c29708e0560dad..0000000000000000000000000000000000000000 --- a/toolbox/sendevent.c +++ /dev/null @@ -1,80 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdint.h> -#include <fcntl.h> -#include <sys/ioctl.h> -//#include <linux/input.h> // this does not compile -#include <errno.h> - - -// from <linux/input.h> - -struct input_event { - struct timeval time; - __u16 type; - __u16 code; - __s32 value; -}; - -#define EVIOCGVERSION _IOR('E', 0x01, int) /* get driver version */ -#define EVIOCGID _IOR('E', 0x02, struct input_id) /* get device ID */ -#define EVIOCGKEYCODE _IOR('E', 0x04, int[2]) /* get keycode */ -#define EVIOCSKEYCODE _IOW('E', 0x04, int[2]) /* set keycode */ - -#define EVIOCGNAME(len) _IOC(_IOC_READ, 'E', 0x06, len) /* get device name */ -#define EVIOCGPHYS(len) _IOC(_IOC_READ, 'E', 0x07, len) /* get physical location */ -#define EVIOCGUNIQ(len) _IOC(_IOC_READ, 'E', 0x08, len) /* get unique identifier */ - -#define EVIOCGKEY(len) _IOC(_IOC_READ, 'E', 0x18, len) /* get global keystate */ -#define EVIOCGLED(len) _IOC(_IOC_READ, 'E', 0x19, len) /* get all LEDs */ -#define EVIOCGSND(len) _IOC(_IOC_READ, 'E', 0x1a, len) /* get all sounds status */ -#define EVIOCGSW(len) _IOC(_IOC_READ, 'E', 0x1b, len) /* get all switch states */ - -#define EVIOCGBIT(ev,len) _IOC(_IOC_READ, 'E', 0x20 + ev, len) /* get event bits */ -#define EVIOCGABS(abs) _IOR('E', 0x40 + abs, struct input_absinfo) /* get abs value/limits */ -#define EVIOCSABS(abs) _IOW('E', 0xc0 + abs, struct input_absinfo) /* set abs value/limits */ - -#define EVIOCSFF _IOC(_IOC_WRITE, 'E', 0x80, sizeof(struct ff_effect)) /* send a force effect to a force feedback device */ -#define EVIOCRMFF _IOW('E', 0x81, int) /* Erase a force effect */ -#define EVIOCGEFFECTS _IOR('E', 0x84, int) /* Report number of effects playable at the same time */ - -#define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */ - -// end <linux/input.h> - - - -int sendevent_main(int argc, char *argv[]) -{ - int i; - int fd; - int ret; - int version; - struct input_event event; - - if(argc != 5) { - fprintf(stderr, "use: %s device type code value\n", argv[0]); - return 1; - } - - fd = open(argv[1], O_RDWR); - if(fd < 0) { - fprintf(stderr, "could not open %s, %s\n", argv[optind], strerror(errno)); - return 1; - } - if (ioctl(fd, EVIOCGVERSION, &version)) { - fprintf(stderr, "could not get driver version for %s, %s\n", argv[optind], strerror(errno)); - return 1; - } - memset(&event, 0, sizeof(event)); - event.type = atoi(argv[2]); - event.code = atoi(argv[3]); - event.value = atoi(argv[4]); - ret = write(fd, &event, sizeof(event)); - if(ret < sizeof(event)) { - fprintf(stderr, "write event failed, %s\n", strerror(errno)); - return -1; - } - return 0; -} diff --git a/toolbox/setconsole.c b/toolbox/setconsole.c deleted file mode 100644 index b0ce13f1974a163c33f71b12dc3ddece93380f28..0000000000000000000000000000000000000000 --- a/toolbox/setconsole.c +++ /dev/null @@ -1,164 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <linux/kd.h> -#include <linux/vt.h> -#include <errno.h> -#include <pthread.h> - -static int activate_thread_switch_vc; -static void *activate_thread(void *arg) -{ - int res; - int fd = (int)arg; - while(activate_thread_switch_vc >= 0) { - do { - res = ioctl(fd, VT_ACTIVATE, (void*)activate_thread_switch_vc); - } while(res < 0 && errno == EINTR); - if (res < 0) { - fprintf(stderr, "ioctl( vcfd, VT_ACTIVATE, vtnum) failed, %d %d %s for %d\n", res, errno, strerror(errno), activate_thread_switch_vc); - } - if(activate_thread_switch_vc >= 0) - sleep(1); - } - return NULL; -} - - -int setconsole_main(int argc, char *argv[]) -{ - int c; - int fd; - int res; - - int mode = -1; - int new_vc = 0; - int close_vc = 0; - int switch_vc = -1; - int printvc = 0; - char *ttydev = "/dev/tty0"; - - do { - c = getopt(argc, argv, "d:gtncv:poh"); - if (c == EOF) - break; - switch (c) { - case 'd': - ttydev = optarg; - break; - case 'g': - if(mode == KD_TEXT) { - fprintf(stderr, "%s: cannot specify both -g and -t\n", argv[0]); - exit(1); - } - mode = KD_GRAPHICS; - break; - case 't': - if(mode == KD_GRAPHICS) { - fprintf(stderr, "%s: cannot specify both -g and -t\n", argv[0]); - exit(1); - } - mode = KD_TEXT; - break; - case 'n': - new_vc = 1; - break; - case 'c': - close_vc = 1; - break; - case 'v': - switch_vc = atoi(optarg); - break; - case 'p': - printvc |= 1; - break; - case 'o': - printvc |= 2; - break; - case 'h': - fprintf(stderr, "%s [-d <dev>] [-v <vc>] [-gtncpoh]\n" - " -d <dev> Use <dev> instead of /dev/tty0\n" - " -v <vc> Switch to virtual console <vc>\n" - " -g Switch to graphics mode\n" - " -t Switch to text mode\n" - " -n Create and switch to new virtual console\n" - " -c Close unused virtual consoles\n" - " -p Print new virtual console\n" - " -o Print old virtual console\n" - " -h Print help\n", argv[0]); - return -1; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - exit(1); - } - } while (1); - if(mode == -1 && new_vc == 0 && close_vc == 0 && switch_vc == -1 && printvc == 0) { - fprintf(stderr,"%s [-d <dev>] [-v <vc>] [-gtncpoh]\n", argv[0]); - return -1; - } - - fd = open(ttydev, O_RDWR | O_SYNC); - if (fd < 0) { - fprintf(stderr, "cannot open %s\n", ttydev); - return -1; - } - - if ((printvc && !new_vc) || (printvc & 2)) { - struct vt_stat vs; - - res = ioctl(fd, VT_GETSTATE, &vs); - if (res < 0) { - fprintf(stderr, "ioctl(vcfd, VT_GETSTATE, &vs) failed, %d\n", res); - } - printf("%d\n", vs.v_active); - } - - if (new_vc) { - int vtnum; - res = ioctl(fd, VT_OPENQRY, &vtnum); - if (res < 0 || vtnum == -1) { - fprintf(stderr, "ioctl(vcfd, VT_OPENQRY, &vtnum) failed, res %d, vtnum %d\n", res, vtnum); - } - switch_vc = vtnum; - } - if (switch_vc != -1) { - pthread_t thread; - pthread_attr_t attr; - activate_thread_switch_vc = switch_vc; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&thread, &attr, activate_thread, (void*)fd); - - do { - res = ioctl(fd, VT_WAITACTIVE, (void*)switch_vc); - } while(res < 0 && errno == EINTR); - activate_thread_switch_vc = -1; - if (res < 0) { - fprintf(stderr, "ioctl( vcfd, VT_WAITACTIVE, vtnum) failed, %d %d %s for %d\n", res, errno, strerror(errno), switch_vc); - } - if(printvc & 1) - printf("%d\n", switch_vc); - - close(fd); - fd = open(ttydev, O_RDWR | O_SYNC); - if (fd < 0) { - fprintf(stderr, "cannot open %s\n", ttydev); - return -1; - } - } - if (close_vc) { - res = ioctl(fd, VT_DISALLOCATE, 0); - if (res < 0) { - fprintf(stderr, "ioctl(vcfd, VT_DISALLOCATE, 0) failed, %d\n", res); - } - } - if (mode != -1) { - if (ioctl(fd, KDSETMODE, (void*)mode) < 0) { - fprintf(stderr, "KDSETMODE %d failed\n", mode); - return -1; - } - } - return 0; -} diff --git a/toolbox/setkey.c b/toolbox/setkey.c deleted file mode 100644 index 1ff27744c0f90c06560d63278c2a0e270e2e1bcc..0000000000000000000000000000000000000000 --- a/toolbox/setkey.c +++ /dev/null @@ -1,89 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <string.h> -#include <linux/kd.h> -#include <linux/vt.h> -#include <errno.h> - -static void setkey_usage(char *argv[]) -{ - fprintf(stderr, "%s [-t <table>] [-k <index>] [-v value] [-r] [-h]\n" - " -t <table> Select table\n" - " -k <index> Select key\n" - " -v <value> Set entry\n" - " -r Read current entry\n" - " -h Print help\n", argv[0]); -} - -#define TTYDEV "/dev/tty0" - -int setkey_main(int argc, char *argv[]) -{ - int fd; - struct kbentry kbe; - int did_something = 0; - - kbe.kb_table = 0; - kbe.kb_index = -1; - kbe.kb_value = 0; - - fd = open(TTYDEV, O_RDWR | O_SYNC); - if (fd < 0) { - fprintf(stderr, "open %s: %s\n", TTYDEV, strerror(errno)); - return 1; - } - - do { - int c, ret; - - c = getopt(argc, argv, "t:k:v:hr"); - if (c == EOF) - break; - - switch (c) { - case 't': - kbe.kb_table = strtol(optarg, NULL, 0); - break; - case 'k': - kbe.kb_index = strtol(optarg, NULL, 0); - break; - case 'v': - kbe.kb_value = strtol(optarg, NULL, 0); - ret = ioctl(fd, KDSKBENT, &kbe); - if (ret < 0) { - fprintf(stderr, "KDSKBENT %d %d %d failed: %s\n", - kbe.kb_table, kbe.kb_index, kbe.kb_value, - strerror(errno)); - return 1; - } - did_something = 1; - break; - case 'r': - ret = ioctl(fd, KDGKBENT, &kbe); - if (ret < 0) { - fprintf(stderr, "KDGKBENT %d %d failed: %s\n", - kbe.kb_table, kbe.kb_index, strerror(errno)); - return 1; - } - printf("0x%x 0x%x 0x%x\n", - kbe.kb_table, kbe.kb_index, kbe.kb_value); - did_something = 1; - break; - case 'h': - setkey_usage(argv); - return 1; - case '?': - fprintf(stderr, "%s: invalid option -%c\n", - argv[0], optopt); - return 1; - } - } while (1); - - if(optind != argc || !did_something) { - setkey_usage(argv); - return 1; - } - - return 0; -} diff --git a/toolbox/setprop.c b/toolbox/setprop.c deleted file mode 100644 index 63ad2b4263b2ba72c6160e58305afc6462642777..0000000000000000000000000000000000000000 --- a/toolbox/setprop.c +++ /dev/null @@ -1,18 +0,0 @@ -#include <stdio.h> - -#include <cutils/properties.h> - -int setprop_main(int argc, char *argv[]) -{ - if(argc != 3) { - fprintf(stderr,"usage: setprop <key> <value>\n"); - return 1; - } - - if(property_set(argv[1], argv[2])){ - fprintf(stderr,"could not set property\n"); - return 1; - } - - return 0; -} diff --git a/toolbox/sleep.c b/toolbox/sleep.c deleted file mode 100644 index c09ae03fab61ad2546792fb9ee3d98ab0399adb4..0000000000000000000000000000000000000000 --- a/toolbox/sleep.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <stdio.h> -#include <unistd.h> -#include <stdlib.h> - -static void -usage(const char *s) -{ - fprintf(stderr, "USAGE: %s SECONDS\n", s); - exit(-1); -} - -int sleep_main(int argc, char *argv[]) -{ - unsigned long seconds; - char *endptr; - - if (argc != 2) { - usage(argv[0]); - } - - seconds = strtoul(argv[1], &endptr, 10); - - if (endptr == argv[1]) { - usage(argv[0]); - } - - - sleep((unsigned int)seconds); - - return 0; -} - - diff --git a/toolbox/smd.c b/toolbox/smd.c deleted file mode 100644 index 65ff994e5ced77167e65a200f01148f4efcff849..0000000000000000000000000000000000000000 --- a/toolbox/smd.c +++ /dev/null @@ -1,40 +0,0 @@ -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <errno.h> - -int smd_main(int argc, char **argv) -{ - int fd, len, r, port = 0; - char devname[32]; - argc--; - argv++; - - if((argc > 0) && (argv[0][0] == '-')) { - port = atoi(argv[0] + 1); - argc--; - argv++; - } - - sprintf(devname,"/dev/smd%d",port); - fd = open(devname, O_WRONLY); - if(fd < 0) { - fprintf(stderr,"failed to open smd0 - %s\n", - strerror(errno)); - return -1; - } - while(argc > 0) { - len = strlen(argv[0]); - r = write(fd, argv[0], len); - if(r != len) { - fprintf(stderr,"failed to write smd0 (%d) %s\n", - r, strerror(errno)); - return -1; - } - argc--; - argv++; - write(fd, argc ? " " : "\r", 1); - } - close(fd); - return 0; -} diff --git a/toolbox/start.c b/toolbox/start.c deleted file mode 100644 index 3bd9fbbbb7ec5b0d265a898e1ea9fe923790fed5..0000000000000000000000000000000000000000 --- a/toolbox/start.c +++ /dev/null @@ -1,20 +0,0 @@ - -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#include <cutils/properties.h> - -int start_main(int argc, char *argv[]) -{ - char buf[1024]; - if(argc > 1) { - property_set("ctl.start", argv[1]); - } else { - /* default to "start zygote" "start runtime" */ - property_set("ctl.start", "zygote"); - property_set("ctl.start", "runtime"); - } - - return 0; -} diff --git a/toolbox/stop.c b/toolbox/stop.c deleted file mode 100644 index 05baffd3827156f02efd67f3324051e9918b71a6..0000000000000000000000000000000000000000 --- a/toolbox/stop.c +++ /dev/null @@ -1,20 +0,0 @@ -#include <stdio.h> -#include <string.h> - -#include <cutils/properties.h> - -int stop_main(int argc, char *argv[]) -{ - char buf[1024]; - - if(argc > 1) { - property_set("ctl.stop", argv[1]); - } else{ - /* default to "stop runtime" "stop zygote" */ - property_set("ctl.stop", "runtime"); - property_set("ctl.stop", "zygote"); - } - - return 0; -} - diff --git a/toolbox/sync.c b/toolbox/sync.c deleted file mode 100644 index 828427634c771f3dc7bdf2c060e012ba5776603e..0000000000000000000000000000000000000000 --- a/toolbox/sync.c +++ /dev/null @@ -1,7 +0,0 @@ -#include <unistd.h> - -int sync_main(int argc, char **argv) -{ - sync(); - return 0; -} diff --git a/toolbox/syren.c b/toolbox/syren.c deleted file mode 100644 index 06e329e99f4fa17ca187f4ce6b114cab2f96ae1c..0000000000000000000000000000000000000000 --- a/toolbox/syren.c +++ /dev/null @@ -1,154 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> -#include <malloc.h> - -/* ioctl crap */ -#define SYREN_RD 101 -#define SYREN_WR 102 -#define SYREN_OLD_RD 108 -#define SYREN_OLD_WR 109 - -struct syren_io_args { - unsigned long page; - unsigned long addr; - unsigned long value; -}; - -typedef struct { - u_char page; - u_char addr; - const char *name; -} syren_reg; - -static syren_reg registers[] = { - { 0, 0x04, "TOGBR1" }, - { 0, 0x05, "TOGBR2" }, - { 0, 0x06, "VBDCTRL" }, - { 1, 0x07, "VBUCTRL" }, - { 1, 0x08, "VBCTRL" }, - { 1, 0x09, "PWDNRG" }, - { 1, 0x0a, "VBPOP" }, - { 1, 0x0b, "VBCTRL2" }, - { 1, 0x0f, "VAUDCTRL" }, - { 1, 0x10, "VAUSCTRL" }, - { 1, 0x11, "VAUOCTRL" }, - { 1, 0x12, "VAUDPLL" }, - { 1, 0x17, "VRPCSIMR" }, - { 0, 0, 0 } -}; - -static syren_reg *find_reg(const char *name) -{ - int i; - - for (i = 0; registers[i].name != 0; i++) { - if (!strcasecmp(registers[i].name, name)) - return ®isters[i]; - } - - return NULL; -} - -static int usage(void) -{ - fprintf(stderr, "usage: syren [r/w] [REGNAME | page:addr] (value)\n"); - return 1; -} - -int -syren_main(int argc, char **argv) -{ - int cmd = -1; - syren_reg *r; - struct syren_io_args sio; - char name[32]; - int fd; - - if (argc < 3) { - return usage(); - } - - switch(argv[1][0]) { - case 'r': - cmd = SYREN_RD; - break; - case 'w': - cmd = SYREN_WR; - break; - case 'R': - cmd = SYREN_OLD_RD; - break; - case 'W': - cmd = SYREN_OLD_WR; - break; - default: - return usage(); - } - - if (cmd == SYREN_WR || cmd == SYREN_OLD_WR) { - if (argc < 4) - return usage(); - sio.value = strtoul(argv[3], 0, 0); - } - - fd = open("/dev/eac", O_RDONLY); - if (fd < 0) { - fprintf(stderr, "can't open /dev/eac\n"); - return 1; - } - - if (strcasecmp(argv[2], "all") == 0) { - int i; - if (cmd != SYREN_RD && cmd != SYREN_OLD_RD) { - fprintf(stderr, "can only read all registers\n"); - return 1; - } - - for (i = 0; registers[i].name; i++) { - sio.page = registers[i].page; - sio.addr = registers[i].addr; - if (ioctl(fd, cmd, &sio) < 0) { - fprintf(stderr, "%s: error\n", registers[i].name); - } else { - fprintf(stderr, "%s: %04x\n", registers[i].name, sio.value); - } - } - - close(fd); - return 0; - } - - r = find_reg(argv[2]); - if (r == NULL) { - strcpy(name, argv[2]); - char *addr_str = strchr(argv[2], ':'); - if (addr_str == NULL) - return usage(); - *addr_str++ = 0; - sio.page = strtoul(argv[2], 0, 0); - sio.addr = strtoul(addr_str, 0, 0); - } else { - strcpy(name, r->name); - sio.page = r->page; - sio.addr = r->addr; - } - - if (ioctl(fd, cmd, &sio) < 0) { - fprintf(stderr, "ioctl(%d) failed\n", cmd); - return 1; - } - - if (cmd == SYREN_RD || cmd == SYREN_OLD_RD) { - printf("%s: %04x\n", name, sio.value); - } else { - printf("wrote %04x to %s\n", sio.value, name); - } - - close(fd); - - return 0; -} - diff --git a/toolbox/toolbox.c b/toolbox/toolbox.c deleted file mode 100644 index 0eac390e498f5bf451f9b34bbfdb9b0ee32af182..0000000000000000000000000000000000000000 --- a/toolbox/toolbox.c +++ /dev/null @@ -1,57 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -int main(int, char **); - -static int toolbox_main(int argc, char **argv) -{ - // "toolbox foo ..." is equivalent to "foo ..." - if (argc > 1) { - return main(argc - 1, argv + 1); - } else { - printf("Toolbox!\n"); - return 0; - } -} - -#define TOOL(name) int name##_main(int, char**); -#include "tools.h" -#undef TOOL - -static struct -{ - const char *name; - int (*func)(int, char**); -} tools[] = { - { "toolbox", toolbox_main }, -#define TOOL(name) { #name, name##_main }, -#include "tools.h" -#undef TOOL - { 0, 0 }, -}; - -int main(int argc, char **argv) -{ - int i; - char *name = argv[0]; - - if((argc > 1) && (argv[1][0] == '@')) { - name = argv[1] + 1; - argc--; - argv++; - } else { - char *cmd = strrchr(argv[0], '/'); - if (cmd) - name = cmd + 1; - } - - for(i = 0; tools[i].name; i++){ - if(!strcmp(tools[i].name, name)){ - return tools[i].func(argc, argv); - } - } - - printf("%s: no such tool\n", argv[0]); - return -1; -} diff --git a/toolbox/top.c b/toolbox/top.c deleted file mode 100644 index dcc084344799acf66f46bccd3563fbadc60c2b3f..0000000000000000000000000000000000000000 --- a/toolbox/top.c +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <ctype.h> -#include <dirent.h> -#include <grp.h> -#include <pwd.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <unistd.h> - -struct cpu_info { - long unsigned utime, ntime, stime, itime; - long unsigned iowtime, irqtime, sirqtime; -}; - -#define PROC_NAME_LEN 64 -#define THREAD_NAME_LEN 32 - -struct proc_info { - struct proc_info *next; - pid_t pid; - pid_t tid; - uid_t uid; - gid_t gid; - char name[PROC_NAME_LEN]; - char tname[THREAD_NAME_LEN]; - char state; - long unsigned utime; - long unsigned stime; - long unsigned delta_utime; - long unsigned delta_stime; - long unsigned delta_time; - long vss; - long rss; - int num_threads; -}; - -struct proc_list { - struct proc_info **array; - int size; -}; - -#define die(...) { fprintf(stderr, __VA_ARGS__); exit(EXIT_FAILURE); } - -#define INIT_PROCS 50 -#define THREAD_MULT 8 -static struct proc_info **old_procs, **new_procs; -static int num_old_procs, num_new_procs; -static struct proc_info *free_procs; -static int num_used_procs, num_free_procs; - -static int max_procs, delay, iterations, threads; - -static struct cpu_info old_cpu, new_cpu; - -static struct proc_info *alloc_proc(void); -static void free_proc(struct proc_info *proc); -static void read_procs(void); -static int read_stat(char *filename, struct proc_info *proc); -static void add_proc(int proc_num, struct proc_info *proc); -static int read_cmdline(char *filename, struct proc_info *proc); -static int read_status(char *filename, struct proc_info *proc); -static void print_procs(void); -static struct proc_info *find_old_proc(pid_t pid, pid_t tid); -static void free_old_procs(void); -static int (*proc_cmp)(const void *a, const void *b); -static int proc_cpu_cmp(const void *a, const void *b); -static int proc_vss_cmp(const void *a, const void *b); -static int proc_rss_cmp(const void *a, const void *b); -static int proc_thr_cmp(const void *a, const void *b); -static int numcmp(long long a, long long b); -static void usage(char *cmd); - -int top_main(int argc, char *argv[]) { - int i; - - num_used_procs = num_free_procs = 0; - - max_procs = 0; - delay = 3; - iterations = -1; - proc_cmp = &proc_cpu_cmp; - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-m")) { - if (i + 1 >= argc) { - fprintf(stderr, "Option -m expects an argument.\n"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - max_procs = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-n")) { - if (i + 1 >= argc) { - fprintf(stderr, "Option -n expects an argument.\n"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - iterations = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-d")) { - if (i + 1 >= argc) { - fprintf(stderr, "Option -d expects an argument.\n"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - delay = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-s")) { - if (i + 1 >= argc) { - fprintf(stderr, "Option -s expects an argument.\n"); - usage(argv[0]); - exit(EXIT_FAILURE); - } - ++i; - if (!strcmp(argv[i], "cpu")) { proc_cmp = &proc_cpu_cmp; continue; } - if (!strcmp(argv[i], "vss")) { proc_cmp = &proc_vss_cmp; continue; } - if (!strcmp(argv[i], "rss")) { proc_cmp = &proc_rss_cmp; continue; } - if (!strcmp(argv[i], "thr")) { proc_cmp = &proc_thr_cmp; continue; } - fprintf(stderr, "Invalid argument \"%s\" for option -s.\n", argv[i]); - exit(EXIT_FAILURE); - } - if (!strcmp(argv[i], "-t")) { threads = 1; continue; } - if (!strcmp(argv[i], "-h")) { - usage(argv[0]); - exit(EXIT_SUCCESS); - } - fprintf(stderr, "Invalid argument \"%s\".\n", argv[i]); - usage(argv[0]); - exit(EXIT_FAILURE); - } - - if (threads && proc_cmp == &proc_thr_cmp) { - fprintf(stderr, "Sorting by threads per thread makes no sense!\n"); - exit(EXIT_FAILURE); - } - - free_procs = NULL; - - num_new_procs = num_old_procs = 0; - new_procs = old_procs = NULL; - - read_procs(); - while ((iterations == -1) || (iterations-- > 0)) { - old_procs = new_procs; - num_old_procs = num_new_procs; - memcpy(&old_cpu, &new_cpu, sizeof(old_cpu)); - sleep(delay); - read_procs(); - print_procs(); - free_old_procs(); - } - - return 0; -} - -static struct proc_info *alloc_proc(void) { - struct proc_info *proc; - - if (free_procs) { - proc = free_procs; - free_procs = free_procs->next; - num_free_procs--; - } else { - proc = malloc(sizeof(*proc)); - if (!proc) die("Could not allocate struct process_info.\n"); - } - - num_used_procs++; - - return proc; -} - -static void free_proc(struct proc_info *proc) { - proc->next = free_procs; - free_procs = proc; - - num_used_procs--; - num_free_procs++; -} - -#define MAX_LINE 256 - -static void read_procs(void) { - DIR *proc_dir, *task_dir; - struct dirent *pid_dir, *tid_dir; - char filename[64]; - FILE *file; - int proc_num; - struct proc_info *proc; - pid_t pid, tid; - - int i; - - proc_dir = opendir("/proc"); - if (!proc_dir) die("Could not open /proc.\n"); - - new_procs = calloc(INIT_PROCS * (threads ? THREAD_MULT : 1), sizeof(struct proc_info *)); - num_new_procs = INIT_PROCS * (threads ? THREAD_MULT : 1); - - file = fopen("/proc/stat", "r"); - if (!file) die("Could not open /proc/stat.\n"); - fscanf(file, "cpu %lu %lu %lu %lu %lu %lu %lu", &new_cpu.utime, &new_cpu.ntime, &new_cpu.stime, - &new_cpu.itime, &new_cpu.iowtime, &new_cpu.irqtime, &new_cpu.sirqtime); - fclose(file); - - proc_num = 0; - while ((pid_dir = readdir(proc_dir))) { - if (!isdigit(pid_dir->d_name[0])) - continue; - - pid = atoi(pid_dir->d_name); - - struct proc_info cur_proc; - - if (!threads) { - proc = alloc_proc(); - - proc->pid = proc->tid = pid; - - sprintf(filename, "/proc/%d/stat", pid); - read_stat(filename, proc); - - sprintf(filename, "/proc/%d/cmdline", pid); - read_cmdline(filename, proc); - - sprintf(filename, "/proc/%d/status", pid); - read_status(filename, proc); - - proc->num_threads = 0; - } else { - sprintf(filename, "/proc/%d/cmdline", pid); - read_cmdline(filename, &cur_proc); - - sprintf(filename, "/proc/%d/status", pid); - read_status(filename, &cur_proc); - - proc = NULL; - } - - sprintf(filename, "/proc/%d/task", pid); - task_dir = opendir(filename); - if (!task_dir) continue; - - while ((tid_dir = readdir(task_dir))) { - if (!isdigit(tid_dir->d_name[0])) - continue; - - if (threads) { - tid = atoi(tid_dir->d_name); - - proc = alloc_proc(); - - proc->pid = pid; proc->tid = tid; - - sprintf(filename, "/proc/%d/task/%d/stat", pid, tid); - read_stat(filename, proc); - - strcpy(proc->name, cur_proc.name); - proc->uid = cur_proc.uid; - proc->gid = cur_proc.gid; - - add_proc(proc_num++, proc); - } else { - proc->num_threads++; - } - } - - closedir(task_dir); - - if (!threads) - add_proc(proc_num++, proc); - } - - for (i = proc_num; i < num_new_procs; i++) - new_procs[i] = NULL; - - closedir(proc_dir); -} - -static int read_stat(char *filename, struct proc_info *proc) { - FILE *file; - char buf[MAX_LINE], *open_paren, *close_paren; - int res, idx; - - file = fopen(filename, "r"); - if (!file) return 1; - fgets(buf, MAX_LINE, file); - fclose(file); - - /* Split at first '(' and last ')' to get process name. */ - open_paren = strchr(buf, '('); - close_paren = strrchr(buf, ')'); - if (!open_paren || !close_paren) return 1; - - *open_paren = *close_paren = '\0'; - strncpy(proc->tname, open_paren + 1, THREAD_NAME_LEN); - proc->tname[THREAD_NAME_LEN-1] = 0; - - /* Scan rest of string. */ - sscanf(close_paren + 1, " %c %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " - "%lu %lu %*d %*d %*d %*d %*d %*d %*d %lu %ld", - &proc->state, &proc->utime, &proc->stime, &proc->vss, &proc->rss); - - return 0; -} - -static void add_proc(int proc_num, struct proc_info *proc) { - int i; - - if (proc_num >= num_new_procs) { - new_procs = realloc(new_procs, 2 * num_new_procs * sizeof(struct proc_info *)); - if (!new_procs) die("Could not expand procs array.\n"); - for (i = num_new_procs; i < 2 * num_new_procs; i++) - new_procs[i] = NULL; - num_new_procs = 2 * num_new_procs; - } - new_procs[proc_num] = proc; -} - -static int read_cmdline(char *filename, struct proc_info *proc) { - FILE *file; - char line[MAX_LINE]; - - line[0] = '\0'; - file = fopen(filename, "r"); - if (!file) return 1; - fgets(line, MAX_LINE, file); - fclose(file); - if (strlen(line) > 0) { - strncpy(proc->name, line, PROC_NAME_LEN); - proc->name[PROC_NAME_LEN-1] = 0; - } else - proc->name[0] = 0; - return 0; -} - -static int read_status(char *filename, struct proc_info *proc) { - FILE *file; - char line[MAX_LINE]; - unsigned int uid, gid; - - file = fopen(filename, "r"); - if (!file) return 1; - while (fgets(line, MAX_LINE, file)) { - sscanf(line, "Uid: %u", &uid); - sscanf(line, "Gid: %u", &gid); - } - fclose(file); - proc->uid = uid; proc->gid = gid; - return 0; -} - -static void print_procs(void) { - int i; - struct proc_info *old_proc, *proc; - long unsigned total_delta_time; - struct passwd *user; - struct group *group; - char *user_str, user_buf[20]; - char *group_str, group_buf[20]; - - for (i = 0; i < num_new_procs; i++) { - if (new_procs[i]) { - old_proc = find_old_proc(new_procs[i]->pid, new_procs[i]->tid); - if (old_proc) { - new_procs[i]->delta_utime = new_procs[i]->utime - old_proc->utime; - new_procs[i]->delta_stime = new_procs[i]->stime - old_proc->stime; - } else { - new_procs[i]->delta_utime = 0; - new_procs[i]->delta_stime = 0; - } - new_procs[i]->delta_time = new_procs[i]->delta_utime + new_procs[i]->delta_stime; - } - } - - total_delta_time = (new_cpu.utime + new_cpu.ntime + new_cpu.stime + new_cpu.itime - + new_cpu.iowtime + new_cpu.irqtime + new_cpu.sirqtime) - - (old_cpu.utime + old_cpu.ntime + old_cpu.stime + old_cpu.itime - + old_cpu.iowtime + old_cpu.irqtime + old_cpu.sirqtime); - - qsort(new_procs, num_new_procs, sizeof(struct proc_info *), proc_cmp); - - printf("\n\n\n"); - printf("User %ld%%, System %ld%%, IOW %ld%%, IRQ %ld%%\n", - ((new_cpu.utime + new_cpu.ntime) - (old_cpu.utime + old_cpu.ntime)) * 100 / total_delta_time, - ((new_cpu.stime ) - (old_cpu.stime)) * 100 / total_delta_time, - ((new_cpu.iowtime) - (old_cpu.iowtime)) * 100 / total_delta_time, - ((new_cpu.irqtime + new_cpu.sirqtime) - - (old_cpu.irqtime + old_cpu.sirqtime)) * 100 / total_delta_time); - printf("User %ld + Nice %ld + Sys %ld + Idle %ld + IOW %ld + IRQ %ld + SIRQ %ld = %ld\n", - new_cpu.utime - old_cpu.utime, - new_cpu.ntime - old_cpu.ntime, - new_cpu.stime - old_cpu.stime, - new_cpu.itime - old_cpu.itime, - new_cpu.iowtime - old_cpu.iowtime, - new_cpu.irqtime - old_cpu.irqtime, - new_cpu.sirqtime - old_cpu.sirqtime, - total_delta_time); - printf("\n"); - if (!threads) - printf("%5s %4s %1s %5s %7s %7s %-8s %s\n", "PID", "CPU%", "S", "#THR", "VSS", "RSS", "UID", "Name"); - else - printf("%5s %5s %4s %1s %7s %7s %-8s %-15s %s\n", "PID", "TID", "CPU%", "S", "VSS", "RSS", "UID", "Thread", "Proc"); - - for (i = 0; i < num_new_procs; i++) { - proc = new_procs[i]; - - if (!proc || (max_procs && (i >= max_procs))) - break; - user = getpwuid(proc->uid); - group = getgrgid(proc->gid); - if (user && user->pw_name) { - user_str = user->pw_name; - } else { - snprintf(user_buf, 20, "%d", proc->uid); - user_str = user_buf; - } - if (group && group->gr_name) { - group_str = group->gr_name; - } else { - snprintf(group_buf, 20, "%d", proc->gid); - group_str = group_buf; - } - if (!threads) - printf("%5d %3ld%% %c %5d %6ldK %6ldK %-8.8s %s\n", proc->pid, proc->delta_time * 100 / total_delta_time, proc->state, proc->num_threads, - proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->name[0] != 0 ? proc->name : proc->tname); - else - printf("%5d %5d %3ld%% %c %6ldK %6ldK %-8.8s %-15s %s\n", proc->pid, proc->tid, proc->delta_time * 100 / total_delta_time, proc->state, - proc->vss / 1024, proc->rss * getpagesize() / 1024, user_str, proc->tname, proc->name); - } -} - -static struct proc_info *find_old_proc(pid_t pid, pid_t tid) { - int i; - - for (i = 0; i < num_old_procs; i++) - if (old_procs[i] && (old_procs[i]->pid == pid) && (old_procs[i]->tid == tid)) - return old_procs[i]; - - return NULL; -} - -static void free_old_procs(void) { - int i; - - for (i = 0; i < num_old_procs; i++) - if (old_procs[i]) - free_proc(old_procs[i]); - - free(old_procs); -} - -static int proc_cpu_cmp(const void *a, const void *b) { - struct proc_info *pa, *pb; - - pa = *((struct proc_info **)a); pb = *((struct proc_info **)b); - - if (!pa && !pb) return 0; - if (!pa) return 1; - if (!pb) return -1; - - return -numcmp(pa->delta_time, pb->delta_time); -} - -static int proc_vss_cmp(const void *a, const void *b) { - struct proc_info *pa, *pb; - - pa = *((struct proc_info **)a); pb = *((struct proc_info **)b); - - if (!pa && !pb) return 0; - if (!pa) return 1; - if (!pb) return -1; - - return -numcmp(pa->vss, pb->vss); -} - -static int proc_rss_cmp(const void *a, const void *b) { - struct proc_info *pa, *pb; - - pa = *((struct proc_info **)a); pb = *((struct proc_info **)b); - - if (!pa && !pb) return 0; - if (!pa) return 1; - if (!pb) return -1; - - return -numcmp(pa->rss, pb->rss); -} - -static int proc_thr_cmp(const void *a, const void *b) { - struct proc_info *pa, *pb; - - pa = *((struct proc_info **)a); pb = *((struct proc_info **)b); - - if (!pa && !pb) return 0; - if (!pa) return 1; - if (!pb) return -1; - - return -numcmp(pa->num_threads, pb->num_threads); -} - -static int numcmp(long long a, long long b) { - if (a < b) return -1; - if (a > b) return 1; - return 0; -} - -static void usage(char *cmd) { - fprintf(stderr, "Usage: %s [ -m max_procs ] [ -n iterations ] [ -d delay ] [ -s sort_column ] [ -t ] [ -h ]\n" - " -m num Maximum number of processes to display.\n" - " -n num Updates to show before exiting.\n" - " -d num Seconds to wait between updates.\n" - " -s col Column to sort by (cpu,vss,rss,thr).\n" - " -t Show threads instead of processes.\n" - " -h Display this help screen.\n", - cmd); -} diff --git a/toolbox/umount.c b/toolbox/umount.c deleted file mode 100644 index 92c60760ba5262a9737af6251c9d68734b4d9a3e..0000000000000000000000000000000000000000 --- a/toolbox/umount.c +++ /dev/null @@ -1,74 +0,0 @@ - -#include <sys/mount.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <linux/loop.h> - -// FIXME - only one loop mount is supported at a time -#define LOOP_DEVICE "/dev/block/loop0" - -static int is_loop_mount(const char* path) -{ - FILE* f; - int count; - char device[256]; - char mount_path[256]; - char rest[256]; - int result = 0; - int path_length = strlen(path); - - f = fopen("/proc/mounts", "r"); - if (!f) { - fprintf(stdout, "could not open /proc/mounts\n"); - return -1; - } - - do { - count = fscanf(f, "%255s %255s %255s\n", device, mount_path, rest); - if (count == 3) { - if (strcmp(LOOP_DEVICE, device) == 0 && strcmp(path, mount_path) == 0) { - result = 1; - break; - } - } - } while (count == 3); - - fclose(f); - return result; -} - -int umount_main(int argc, char *argv[]) -{ - int loop, loop_fd; - - if(argc != 2) { - fprintf(stderr,"umount <path>\n"); - return 1; - } - - loop = is_loop_mount(argv[1]); - if(umount(argv[1])){ - fprintf(stderr,"failed.\n"); - return 1; - } - - if (loop) { - // free the loop device - loop_fd = open(LOOP_DEVICE, O_RDONLY); - if (loop_fd < -1) { - perror("open loop device failed"); - return 1; - } - if (ioctl(loop_fd, LOOP_CLR_FD, 0) < 0) { - perror("ioctl LOOP_CLR_FD failed"); - return 1; - } - - close(loop_fd); - } - - return 0; -} diff --git a/toolbox/vmstat.c b/toolbox/vmstat.c deleted file mode 100644 index 600f1364034cb6e7a300a5cdc160666a3988d7c9..0000000000000000000000000000000000000000 --- a/toolbox/vmstat.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2008, The Android Open Source Project - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * 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. - * * Neither the name of Google, Inc. 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 COPYRIGHT HOLDERS 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 - * COPYRIGHT OWNER 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. - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <sys/param.h> -#include <unistd.h> - -struct state { - long procs_r; - long procs_b; - - long mem_free; - long mem_mapped; - long mem_anon; - long mem_slab; - - long sys_in; - long sys_cs; - long sys_flt; - - long cpu_us; - long cpu_ni; - long cpu_sy; - long cpu_id; - long cpu_wa; - long cpu_ir; - long cpu_si; -}; - -#define MAX_LINE 256 - -char line[MAX_LINE]; - -static void read_state(struct state *s); -static int read_meminfo(struct state *s); -static int read_stat(struct state *s); -static int read_vmstat(struct state *s); -static void print_header(void); -static void print_line(struct state *old, struct state *new); -static void usage(char *cmd); - -int vmstat_main(int argc, char *argv[]) { - struct state s[2]; - int iterations, delay, header_interval; - int toggle, count; - int i; - - iterations = 0; - delay = 1; - header_interval = 20; - - for (i = 1; i < argc; i++) { - if (!strcmp(argv[i], "-n")) { - if (i >= argc - 1) { - fprintf(stderr, "Option -n requires an argument.\n"); - exit(EXIT_FAILURE); - } - iterations = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-d")) { - if (i >= argc - 1) { - fprintf(stderr, "Option -d requires an argument.\n"); - exit(EXIT_FAILURE); - } - delay = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-r")) { - if (i >= argc - 1) { - fprintf(stderr, "Option -r requires an argument.\n"); - exit(EXIT_FAILURE); - } - header_interval = atoi(argv[++i]); - continue; - } - if (!strcmp(argv[i], "-h")) { - usage(argv[0]); - exit(EXIT_SUCCESS); - } - fprintf(stderr, "Invalid argument \"%s\".\n", argv[i]); - usage(argv[0]); - exit(EXIT_FAILURE); - } - - toggle = 0; - count = 0; - - if (!header_interval) - print_header(); - read_state(&s[1 - toggle]); - while ((iterations == 0) || (iterations-- > 0)) { - sleep(delay); - read_state(&s[toggle]); - if (header_interval) { - if (count == 0) - print_header(); - count = (count + 1) % header_interval; - } - print_line(&s[1 - toggle], &s[toggle]); - toggle = 1 - toggle; - } - - return 0; -} - -static void read_state(struct state *s) { - int error; - - error = read_meminfo(s); - if (error) { - fprintf(stderr, "vmstat: could not read /proc/meminfo: %s\n", strerror(error)); - exit(EXIT_FAILURE); - } - - error = read_stat(s); - if (error) { - fprintf(stderr, "vmstat: could not read /proc/stat: %s\n", strerror(error)); - exit(EXIT_FAILURE); - } - - error = read_vmstat(s); - if (error) { - fprintf(stderr, "vmstat: could not read /proc/vmstat: %s\n", strerror(error)); - exit(EXIT_FAILURE); - } -} - -static int read_meminfo(struct state *s) { - FILE *f; - - f = fopen("/proc/meminfo", "r"); - if (!f) return errno; - - while (fgets(line, MAX_LINE, f)) { - sscanf(line, "MemFree: %ld kB", &s->mem_free); - sscanf(line, "AnonPages: %ld kB", &s->mem_anon); - sscanf(line, "Mapped: %ld kB", &s->mem_mapped); - sscanf(line, "Slab: %ld kB", &s->mem_slab); - } - - fclose(f); - - return 0; -} - -static int read_stat(struct state *s) { - FILE *f; - - f = fopen("/proc/stat", "r"); - if (!f) return errno; - - while (fgets(line, MAX_LINE, f)) { - if (!strncmp(line, "cpu ", 4)) { - sscanf(line, "cpu %ld %ld %ld %ld %ld %ld %ld", - &s->cpu_us, &s->cpu_ni, &s->cpu_sy, &s->cpu_id, &s->cpu_wa, - &s->cpu_ir, &s->cpu_si); - } - sscanf(line, "intr %ld", &s->sys_in); - sscanf(line, "ctxt %ld", &s->sys_cs); - sscanf(line, "procs_running %ld", &s->procs_r); - sscanf(line, "procs_blocked %ld", &s->procs_b); - } - - fclose(f); - - return 0; -} - -static int read_vmstat(struct state *s) { - FILE *f; - - f = fopen("/proc/vmstat", "r"); - if (!f) return errno; - - while (fgets(line, MAX_LINE, f)) { - sscanf(line, "pgmajfault %ld", &s->sys_flt); - } - - fclose(f); - - return 0; -} - -static void print_header(void) { - printf("%-5s %-27s %-14s %-17s\n", "procs", "memory", "system", "cpu"); - printf("%2s %2s %6s %6s %6s %6s %4s %4s %4s %2s %2s %2s %2s %2s %2s\n", "r", "b", "free", "mapped", "anon", "slab", "in", "cs", "flt", "us", "ni", "sy", "id", "wa", "ir"); -} - -/* Jiffies to percent conversion */ -#define JP(jif) ((jif) * 100 / (HZ)) -#define NORM(var) ((var) = (((var) > 99) ? (99) : (var))) - -static void print_line(struct state *old, struct state *new) { - int us, ni, sy, id, wa, ir; - us = JP(new->cpu_us - old->cpu_us); NORM(us); - ni = JP(new->cpu_ni - old->cpu_ni); NORM(ni); - sy = JP(new->cpu_sy - old->cpu_sy); NORM(sy); - id = JP(new->cpu_id - old->cpu_id); NORM(id); - wa = JP(new->cpu_wa - old->cpu_wa); NORM(wa); - ir = JP(new->cpu_ir - old->cpu_ir); NORM(ir); - printf("%2ld %2ld %6ld %6ld %6ld %6ld %4ld %4ld %4ld %2d %2d %2d %2d %2d %2d\n", - new->procs_r ? (new->procs_r - 1) : 0, new->procs_b, - new->mem_free, new->mem_mapped, new->mem_anon, new->mem_slab, - new->sys_in - old->sys_in, new->sys_cs - old->sys_cs, new->sys_flt - old->sys_flt, - us, ni, sy, id, wa, ir); -} - -static void usage(char *cmd) { - fprintf(stderr, "Usage: %s [ -h ] [ -n iterations ] [ -d delay ] [ -r header_repeat ]\n" - " -n iterations How many rows of data to print.\n" - " -d delay How long to sleep between rows.\n" - " -r header_repeat How many rows to print before repeating\n" - " the header. Zero means never repeat.\n" - " -h Displays this help screen.\n", - cmd); -} diff --git a/toolbox/watchprops.c b/toolbox/watchprops.c deleted file mode 100644 index d3119924b03a20d57cb35613d80bad0fb6ac72e5..0000000000000000000000000000000000000000 --- a/toolbox/watchprops.c +++ /dev/null @@ -1,76 +0,0 @@ -#include <stdio.h> -#include <stdlib.h> -#include <time.h> - -#include <cutils/properties.h> - -#include <sys/atomics.h> - -#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_ -#include <sys/_system_properties.h> - - -extern prop_area *__system_property_area__; - -typedef struct pwatch pwatch; - -struct pwatch -{ - const prop_info *pi; - unsigned serial; -}; - -static pwatch watchlist[1024]; - -static void announce(const prop_info *pi) -{ - char name[PROP_NAME_MAX]; - char value[PROP_VALUE_MAX]; - char *x; - - __system_property_read(pi, name, value); - - for(x = value; *x; x++) { - if((*x < 32) || (*x > 127)) *x = '.'; - } - - fprintf(stderr,"%10d %s = '%s'\n", (int) time(0), name, value); -} - -int watchprops_main(int argc, char *argv[]) -{ - prop_area *pa = __system_property_area__; - unsigned serial = pa->serial; - unsigned count = pa->count; - unsigned n; - - if(count >= 1024) exit(1); - - for(n = 0; n < count; n++) { - watchlist[n].pi = __system_property_find_nth(n); - watchlist[n].serial = watchlist[n].pi->serial; - } - - for(;;) { - do { - __futex_wait(&pa->serial, serial, 0); - } while(pa->serial == serial); - - while(count < pa->count){ - watchlist[count].pi = __system_property_find_nth(count); - watchlist[count].serial = watchlist[n].pi->serial; - announce(watchlist[count].pi); - count++; - if(count == 1024) exit(1); - } - - for(n = 0; n < count; n++){ - unsigned tmp = watchlist[n].pi->serial; - if(watchlist[n].serial != tmp) { - announce(watchlist[n].pi); - watchlist[n].serial = tmp; - } - } - } - return 0; -} diff --git a/toolbox/wipe.c b/toolbox/wipe.c deleted file mode 100644 index 7e263fd44cd0360ec3ca36685df6d6b2848163f1..0000000000000000000000000000000000000000 --- a/toolbox/wipe.c +++ /dev/null @@ -1,176 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <dirent.h> -#include <string.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/reboot.h> -#include <sys/stat.h> - -#ifndef PATH_MAX -#define PATH_MAX 4096 -#endif - - -/* Directories created by init defined in system/rootdir/init.rc */ -static char *INIT_DIRS[] = { - "/system/etc/ppp", - "/data/misc", - "/data/local", - "/data/local/tmp", - "/data/data", - "/data/app_private", - "/data/app", - NULL -}; - -static void wipe (const char *path); - -static int usage() -{ - fprintf(stderr, "wipe <system|data|all>\n\n" - "system means '/system'\n" - "data means '/data'\n"); - - return -1; -} - -int wipe_main (int argc, char *argv[]) -{ - char *whatToWipe; - - if (argc != 2) return usage(); - - whatToWipe = argv[1]; - - if (0 == strcmp (whatToWipe, "system")) { - fprintf(stdout, "Wiping /system\n"); - wipe ("/system"); - fprintf(stdout, "Done wiping /android\n"); - } else if (0 == strcmp (whatToWipe, "data")) { - fprintf(stdout, "Wiping /data\n"); - wipe ("/data"); - fprintf(stdout, "Done wiping /data\n"); - } else if (0 == strcmp (whatToWipe, "all")) { - fprintf(stdout, "Wiping /system and /data\n"); - wipe ("/system"); - wipe ("/data"); - fprintf(stdout, "Done wiping /system and /data\n"); - } else if (0 == strcmp(whatToWipe, "nuke")) { - int ret; - fprintf(stdout, "Nuking the device...\n"); - wipe ("/system"); - wipe ("/data"); - fprintf(stdout, "Device nuked! Rebooting...\n"); - ret = reboot(RB_AUTOBOOT); - if (ret < 0) { - fprintf(stderr, "Reboot failed, %s\n", strerror(errno)); - return 1; - } - } else { - return usage(); - } - - return 0; -} - -static char nameBuffer[PATH_MAX]; -static struct stat statBuffer; - -static void wipe (const char *path) -{ - DIR *dir; - struct dirent *de; - int ret; - - dir = opendir(path); - - if (dir == NULL) { - fprintf (stderr, "Error opendir'ing %s '%s'\n", - path, strerror(errno)); - return; - } - - char *filenameOffset; - - strcpy(nameBuffer, path); - strcat(nameBuffer, "/"); - - filenameOffset = nameBuffer + strlen(nameBuffer); - - for (;;) { - de = readdir(dir); - - if (de == NULL) { - break; - } - - if (0 == strcmp(de->d_name, ".") - || 0 == strcmp(de->d_name, "..") - || 0 == strcmp(de->d_name, "lost+found") - ) { - continue; - } - - strcpy(filenameOffset, de->d_name); - - ret = lstat (nameBuffer, &statBuffer); - - if (ret != 0) { - fprintf(stderr, "stat() error on '%s' '%s'\n", - nameBuffer, strerror(errno)); - } - - if(S_ISDIR(statBuffer.st_mode)) { - int i; - char *newpath; - -#if 0 - closedir(dir); -#endif - - newpath = strdup(nameBuffer); - wipe(newpath); - - /* Leave directories created by init, they have special permissions. */ - for (i = 0; INIT_DIRS[i]; i++) { - if (strcmp(INIT_DIRS[i], newpath) == 0) { - break; - } - } - if (INIT_DIRS[i] == NULL) { - ret = rmdir(newpath); - if (ret != 0) { - fprintf(stderr, "rmdir() error on '%s' '%s'\n", - newpath, strerror(errno)); - } - } - - free(newpath); - -#if 0 - dir = opendir(path); - if (dir == NULL) { - fprintf (stderr, "Error opendir'ing %s '%s'\n", - path, strerror(errno)); - return; - } -#endif - - strcpy(nameBuffer, path); - strcat(nameBuffer, "/"); - - } else { - ret = unlink(nameBuffer); - - if (ret != 0) { - fprintf(stderr, "unlink() error on '%s' '%s'\n", - nameBuffer, strerror(errno)); - } - } - } - - closedir(dir); - -} diff --git a/vold/Android.mk b/vold/Android.mk deleted file mode 100644 index 3dd9f871b71a975ed8c68c2b4fc165c6b11ffe1c..0000000000000000000000000000000000000000 --- a/vold/Android.mk +++ /dev/null @@ -1,32 +0,0 @@ -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES:= \ - vold.c \ - cmd_dispatch.c \ - uevent.c \ - mmc.c \ - misc.c \ - blkdev.c \ - ums.c \ - geom_mbr_enc.c \ - volmgr.c \ - media.c \ - volmgr_vfat.c \ - volmgr_ext3.c \ - logwrapper.c \ - ProcessKiller.c\ - switch.c \ - format.c \ - devmapper.c - -LOCAL_MODULE:= vold - -LOCAL_C_INCLUDES := $(KERNEL_HEADERS) - -LOCAL_CFLAGS := - -LOCAL_SHARED_LIBRARIES := libcutils - -include $(BUILD_EXECUTABLE) diff --git a/vold/ProcessKiller.c b/vold/ProcessKiller.c deleted file mode 100644 index fc3eb3704f597747e1407c1f30fe7aaa0439bd3d..0000000000000000000000000000000000000000 --- a/vold/ProcessKiller.c +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* -** mountd process killer -*/ - -#include "vold.h" - -#include <stdio.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <dirent.h> -#include <ctype.h> -#include <pwd.h> -#include <stdlib.h> -#include <poll.h> -#include <sys/stat.h> - - -static boolean ReadSymLink(const char* path, char* link) -{ - struct stat s; - int length; - - if (lstat(path, &s) < 0) - return false; - if ((s.st_mode & S_IFMT) != S_IFLNK) - return false; - - // we have a symlink - length = readlink(path, link, PATH_MAX - 1); - if (length <= 0) - return false; - link[length] = 0; - return true; -} - -static boolean PathMatchesMountPoint(const char* path, const char* mountPoint) -{ - int length = strlen(mountPoint); - if (length > 1 && strncmp(path, mountPoint, length) == 0) - { - // we need to do extra checking if mountPoint does not end in a '/' - if (mountPoint[length - 1] == '/') - return true; - // if mountPoint does not have a trailing slash, we need to make sure - // there is one in the path to avoid partial matches. - return (path[length] == 0 || path[length] == '/'); - } - - return false; -} - -static void GetProcessName(int pid, char buffer[PATH_MAX]) -{ - int fd; - sprintf(buffer, "/proc/%d/cmdline", pid); - fd = open(buffer, O_RDONLY); - if (fd < 0) { - strcpy(buffer, "???"); - } else { - int length = read(fd, buffer, PATH_MAX - 1); - buffer[length] = 0; - close(fd); - } -} - -static boolean CheckFileDescriptorSymLinks(int pid, const char* mountPoint) -{ - DIR* dir; - struct dirent* de; - boolean fileOpen = false; - char path[PATH_MAX]; - char link[PATH_MAX]; - int parent_length; - - // compute path to process's directory of open files - sprintf(path, "/proc/%d/fd", pid); - dir = opendir(path); - if (!dir) - return false; - - // remember length of the path - parent_length = strlen(path); - // append a trailing '/' - path[parent_length++] = '/'; - - while ((de = readdir(dir)) != 0 && !fileOpen) { - if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) - continue; - - // append the file name, after truncating to parent directory - path[parent_length] = 0; - strcat(path, de->d_name); - - if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has open file %s", name, pid, link); - fileOpen = true; - } - } - - closedir(dir); - return fileOpen; -} - -static boolean CheckFileMaps(int pid, const char* mountPoint) -{ - FILE* file; - char buffer[PATH_MAX + 100]; - boolean mapOpen = false; - - sprintf(buffer, "/proc/%d/maps", pid); - file = fopen(buffer, "r"); - if (!file) - return false; - - while (!mapOpen && fgets(buffer, sizeof(buffer), file)) - { - // skip to the path - const char* path = strchr(buffer, '/'); - if (path && PathMatchesMountPoint(path, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has open file map for %s", name, pid, path); - mapOpen = true; - } - } - - fclose(file); - return mapOpen; -} - -static boolean CheckSymLink(int pid, const char* mountPoint, const char* name, const char* message) -{ - char path[PATH_MAX]; - char link[PATH_MAX]; - - sprintf(path, "/proc/%d/%s", pid, name); - if (ReadSymLink(path, link) && PathMatchesMountPoint(link, mountPoint)) - { - char name[PATH_MAX]; - GetProcessName(pid, name); - LOG_ERROR("process %s (%d) has %s in %s", name, pid, message, mountPoint); - return true; - } - else - return false; -} - -static int get_pid(const char* s) -{ - int result = 0; - while (*s) { - if (!isdigit(*s)) return -1; - result = 10 * result + (*s++ - '0'); - } - return result; -} - -// hunt down and kill processes that have files open on the given mount point -void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *excluded, int num_excluded) -{ - DIR* dir; - struct dirent* de; - - LOG_ERROR("KillProcessesWithOpenFiles %s", mountPoint); - dir = opendir("/proc"); - if (!dir) return; - - while ((de = readdir(dir)) != 0) - { - boolean killed = false; - // does the name look like a process ID? - int pid = get_pid(de->d_name); - if (pid == -1) continue; - - if (CheckFileDescriptorSymLinks(pid, mountPoint) // check for open files - || CheckFileMaps(pid, mountPoint) // check for mmap() - || CheckSymLink(pid, mountPoint, "cwd", "working directory") // check working directory - || CheckSymLink(pid, mountPoint, "root", "chroot") // check for chroot() - || CheckSymLink(pid, mountPoint, "exe", "executable path") // check executable path - ) - { - int i; - boolean hit = false; - - for (i = 0; i < num_excluded; i++) { - if (pid == excluded[i]) { - LOG_ERROR("I just need a little more TIME captain!"); - hit = true; - break; - } - } - - if (!hit) { - LOG_ERROR("Killing process %d", pid); - kill(pid, (sigkill ? SIGKILL : SIGTERM)); - } - } - } - - closedir(dir); -} diff --git a/vold/blkdev.c b/vold/blkdev.c deleted file mode 100644 index 131fd5a2613317e94aa58e2fb315670d75ce86a7..0000000000000000000000000000000000000000 --- a/vold/blkdev.c +++ /dev/null @@ -1,319 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> -#include <fcntl.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/mman.h> - -#include <linux/fs.h> -#include <linux/msdos_fs.h> - -#include "vold.h" -#include "blkdev.h" -#include "diskmbr.h" - -#define DEBUG_BLKDEV 0 - -static blkdev_list_t *list_root = NULL; - -static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major, - int minor, char *type, struct media *media); - -static int fat_valid_media(unsigned char media) -{ - return 0xf8 <= media || media == 0xf0; -} - -char *blkdev_get_devpath(blkdev_t *blk) -{ - char *dp = malloc(256); - sprintf(dp, "%s/vold/%d:%d", DEVPATH, blk->major, blk->minor); - return dp; -} - -int blkdev_refresh(blkdev_t *blk) -{ - int fd = 0; - char *devpath = NULL; - unsigned char *block = NULL; - int i, rc; - - if (!(block = malloc(512))) - goto out; - - /* - * Get the device size - */ - devpath = blkdev_get_devpath(blk); - - if ((fd = open(devpath, O_RDONLY)) < 0) { - LOGE("Unable to open device '%s' (%s)", devpath, strerror(errno)); - return -errno; - } - - if (ioctl(fd, BLKGETSIZE, &blk->nr_sec)) { - LOGE("Unable to get device size (%m)"); - return -errno; - } - close(fd); - free(devpath); - - /* - * Open the disk partition table - */ - devpath = blkdev_get_devpath(blk->disk); - if ((fd = open(devpath, O_RDONLY)) < 0) { - LOGE("Unable to open device '%s' (%s)", devpath, - strerror(errno)); - free(devpath); - return -errno; - } - - free(devpath); - - if ((rc = read(fd, block, 512)) != 512) { - LOGE("Unable to read device partition table (%d, %s)", - rc, strerror(errno)); - goto out; - } - - /* - * If we're a disk, then process the partition table. Otherwise we're - * a partition so get the partition type - */ - - if (blk->type == blkdev_disk) { - blk->nr_parts = 0; - - if ((block[0x1fe] != 0x55) || (block[0x1ff] != 0xAA)) { - LOG_VOL("Disk %d:%d does not contain a partition table", - blk->major, blk->minor); - goto out; - } - - for (i = 0; i < 4; i++) { - struct dos_partition part; - - dos_partition_dec(block + DOSPARTOFF + i * sizeof(struct dos_partition), &part); - if (part.dp_flag != 0 && part.dp_flag != 0x80) { - struct fat_boot_sector *fb = (struct fat_boot_sector *) &block[0]; - - if (!i && fb->reserved && fb->fats && fat_valid_media(fb->media)) { - LOG_VOL("Detected FAT filesystem in partition table"); - break; - } else { - LOG_VOL("Partition table looks corrupt"); - break; - } - } - if (part.dp_size != 0 && part.dp_typ != 0) - blk->nr_parts++; - } - } else if (blk->type == blkdev_partition) { - struct dos_partition part; - int part_no = blk->minor -1; - - dos_partition_dec(block + DOSPARTOFF + part_no * sizeof(struct dos_partition), &part); - blk->part_type = part.dp_typ; - } - - out: - - if (block) - free(block); - - char tmp[255]; - char tmp2[32]; - sprintf(tmp, "%s (blkdev %d:%d), %u secs (%u MB)", - (blk->type == blkdev_disk ? "Disk" : "Partition"), - blk->major, blk->minor, - blk->nr_sec, - ((blk->nr_sec * 512) / 1024) / 1024); - - if (blk->type == blkdev_disk) - sprintf(tmp2, " %d partitions", blk->nr_parts); - else - sprintf(tmp2, " type 0x%x", blk->part_type); - - strcat(tmp, tmp2); - LOG_VOL(tmp); - - close(fd); - - return 0; -} - -blkdev_t *blkdev_create(blkdev_t *disk, char *devpath, int major, int minor, struct media *media, char *type) -{ - return _blkdev_create(disk, devpath, major, minor, type, media); -} - -static blkdev_t *_blkdev_create(blkdev_t *disk, char *devpath, int major, - int minor, char *type, struct media *media) -{ - blkdev_t *new; - struct blkdev_list *list_entry; - - if (disk && disk->type != blkdev_disk) { - LOGE("Non disk parent specified for blkdev!"); - return NULL; - } - - if (!(new = malloc(sizeof(blkdev_t)))) - return NULL; - - memset(new, 0, sizeof(blkdev_t)); - - if (!(list_entry = malloc(sizeof(struct blkdev_list)))) { - free (new); - return NULL; - } - list_entry->dev = new; - list_entry->next = NULL; - - if (!list_root) - list_root = list_entry; - else { - struct blkdev_list *list_scan = list_root; - while (list_scan->next) - list_scan = list_scan->next; - list_scan->next = list_entry; - } - - if (devpath) - new->devpath = strdup(devpath); - new->major = major; - new->minor = minor; - new->media = media; - new->nr_sec = 0xffffffff; - - if (disk) - new->disk = disk; - else - new->disk = new; // Note the self disk pointer - - /* Create device nodes */ - char nodepath[255]; - mode_t mode = 0666 | S_IFBLK; - dev_t dev = (major << 8) | minor; - - sprintf(nodepath, "%s/vold/%d:%d", DEVPATH, major, minor); - if (mknod(nodepath, mode, dev) < 0) { - LOGE("Error making device nodes for '%s' (%s)", - nodepath, strerror(errno)); - } - - if (!strcmp(type, "disk")) - new->type = blkdev_disk; - else if (!strcmp(type, "partition")) - new->type = blkdev_partition; - else { - LOGE("Unknown block device type '%s'", type); - new->type = blkdev_unknown; - } - - return new; -} - -void blkdev_destroy(blkdev_t *blkdev) -{ - struct blkdev_list *list_next; - - if (list_root->dev == blkdev) { - list_next = list_root->next; - free (list_root); - list_root = list_next; - } else { - struct blkdev_list *list_scan = list_root; - while (list_scan->next->dev != blkdev) - list_scan = list_scan -> next; - list_next = list_scan->next->next; - free(list_scan->next); - list_scan->next = list_next; - } - - if (blkdev->devpath) - free(blkdev->devpath); - - char nodepath[255]; - sprintf(nodepath, "%s/vold/%d:%d", DEVPATH, blkdev->major, blkdev->minor); - unlink(nodepath); - - free(blkdev); -} - -blkdev_t *blkdev_lookup_by_path(char *devpath) -{ - struct blkdev_list *list_scan = list_root; - - while (list_scan) { - if (!strcmp(list_scan->dev->devpath, devpath)) - return list_scan->dev; - list_scan = list_scan->next; - } - return NULL; -} - -blkdev_t *blkdev_lookup_by_devno(int maj, int min) -{ - struct blkdev_list *list_scan = list_root; - - while (list_scan) { - if ((list_scan->dev->major == maj) && - (list_scan->dev->minor == min)) - return list_scan->dev; - list_scan = list_scan->next; - } - return NULL; -} - -/* - * Given a disk device, return the number of partitions which - * have yet to be processed. - */ -int blkdev_get_num_pending_partitions(blkdev_t *blk) -{ - struct blkdev_list *list_scan = list_root; - int num = blk->nr_parts; - - if (blk->type != blkdev_disk) - return -EINVAL; - - while (list_scan) { - if (list_scan->dev->type != blkdev_partition) - goto next; - - if (list_scan->dev->major != blk->major) - goto next; - - if (list_scan->dev->nr_sec != 0xffffffff && - list_scan->dev->devpath) { - num--; - } - next: - list_scan = list_scan->next; - } - return num; -} - diff --git a/vold/blkdev.h b/vold/blkdev.h deleted file mode 100644 index e789739efd4232b5e45258ab75cd71eb5d9d1ba9..0000000000000000000000000000000000000000 --- a/vold/blkdev.h +++ /dev/null @@ -1,64 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _BLKDEV_H -#define _BLKDEV_H - -#include <sys/types.h> - -struct media; - -enum blk_type { blkdev_unknown, blkdev_disk, blkdev_partition }; - -struct blkdev { - char *devpath; - enum blk_type type; - struct media *media; - - // If type == blkdev_disk then nr_parts = number of partitions - int nr_parts; - - // If type == blkdev_partition then part_type = partition type - uint8_t part_type; - // If type == blkdev_partition - struct blkdev *disk; - - unsigned int nr_sec; - - int major; - int minor; -}; - -struct blkdev_list { - struct blkdev *dev; - struct blkdev_list *next; -}; - -typedef struct blkdev blkdev_t; -typedef struct blkdev_list blkdev_list_t; - -blkdev_t *blkdev_create(blkdev_t *disk, char *devpath, int major, int minor, struct media *media, char *type); -blkdev_t *blkdev_create_pending_partition(blkdev_t *disk, char *dev_fspath, int major, int minor, struct media *media); -blkdev_t *blkdev_lookup_by_path(char *devpath); -blkdev_t *blkdev_lookup_by_devno(int maj, int min); -char *blkdev_get_devpath(blkdev_t *blk); - -void blkdev_destroy(blkdev_t *blk); - -int blkdev_get_num_pending_partitions(blkdev_t *blk); -int blkdev_refresh(blkdev_t *blk); -#endif diff --git a/vold/cmd_dispatch.c b/vold/cmd_dispatch.c deleted file mode 100644 index ab65fd9663d7b0ae1024635ff09ec734d6e320b6..0000000000000000000000000000000000000000 --- a/vold/cmd_dispatch.c +++ /dev/null @@ -1,115 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <unistd.h> -#include <errno.h> - -#include "vold.h" -#include "cmd_dispatch.h" -#include "ums.h" -#include "volmgr.h" - -struct cmd_dispatch { - char *cmd; - int (* dispatch) (char *); -}; - -static void dispatch_cmd(char *cmd); -static int do_send_ums_status(char *cmd); -static int do_set_ums_enable(char *cmd); -static int do_mount_volume(char *cmd); -static int do_eject_media(char *cmd); -static int do_format_media(char *cmd); - -static struct cmd_dispatch dispatch_table[] = { - { VOLD_CMD_ENABLE_UMS, do_set_ums_enable }, - { VOLD_CMD_DISABLE_UMS, do_set_ums_enable }, - { VOLD_CMD_SEND_UMS_STATUS, do_send_ums_status }, - { VOLD_CMD_MOUNT_VOLUME, do_mount_volume }, - { VOLD_CMD_EJECT_MEDIA, do_eject_media }, - { VOLD_CMD_FORMAT_MEDIA, do_format_media }, - { NULL, NULL } -}; - -int process_framework_command(int socket) -{ - int rc; - char buffer[101]; - - if ((rc = read(socket, buffer, sizeof(buffer) -1)) < 0) { - LOGE("Unable to read framework command (%s)", strerror(errno)); - return -errno; - } else if (!rc) - return -ECONNRESET; - - int start = 0; - int i; - - buffer[rc] = 0; - - for (i = 0; i < rc; i++) { - if (buffer[i] == 0) { - dispatch_cmd(buffer + start); - start = i + 1; - } - } - return 0; -} - -static void dispatch_cmd(char *cmd) -{ - struct cmd_dispatch *c; - - LOG_VOL("dispatch_cmd(%s):", cmd); - - for (c = dispatch_table; c->cmd != NULL; c++) { - if (!strncmp(c->cmd, cmd, strlen(c->cmd))) { - c->dispatch(cmd); - return; - } - } - - LOGE("No cmd handlers defined for '%s'", cmd); -} - -static int do_send_ums_status(char *cmd) -{ - return ums_send_status(); -} - -static int do_set_ums_enable(char *cmd) -{ - if (!strcmp(cmd, VOLD_CMD_ENABLE_UMS)) - return volmgr_enable_ums(true); - - return volmgr_enable_ums(false); -} - -static int do_mount_volume(char *cmd) -{ - return volmgr_start_volume_by_mountpoint(&cmd[strlen("mount_volume:")]); -} - -static int do_format_media(char *cmd) -{ - return volmgr_format_volume(&cmd[strlen("format_media:")]); -} - -static int do_eject_media(char *cmd) -{ - return volmgr_stop_volume_by_mountpoint(&cmd[strlen("eject_media:")]); -} diff --git a/vold/cmd_dispatch.h b/vold/cmd_dispatch.h deleted file mode 100644 index f8ba6b3d9e72aa95fd46d38ffc7247ff17609bf1..0000000000000000000000000000000000000000 --- a/vold/cmd_dispatch.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _CMD_DISPATCH_H -#define _CMD_DISPATCH_H - -// These must match the strings in java/android/android/os/UsbListener.java -#define VOLD_CMD_ENABLE_UMS "enable_ums" -#define VOLD_CMD_DISABLE_UMS "disable_ums" -#define VOLD_CMD_SEND_UMS_STATUS "send_ums_status" - -// these commands should contain a volume mount point after the colon -#define VOLD_CMD_MOUNT_VOLUME "mount_volume:" -#define VOLD_CMD_EJECT_MEDIA "eject_media:" -#define VOLD_CMD_FORMAT_MEDIA "format_media:" - -#endif diff --git a/vold/devmapper.c b/vold/devmapper.c deleted file mode 100644 index ef44c90eab92c5055e346740d3b9174abc7e362a..0000000000000000000000000000000000000000 --- a/vold/devmapper.c +++ /dev/null @@ -1,463 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <unistd.h> -#include <sched.h> -#include <fcntl.h> - -#include <sys/mount.h> - -#include <linux/loop.h> -#include <linux/dm-ioctl.h> - -#include <cutils/config_utils.h> -#include <cutils/properties.h> - -#include "vold.h" -#include "devmapper.h" - -#define DEBUG_DEVMAPPER 1 - -static void *_align(void *ptr, unsigned int a) -{ - register unsigned long agn = --a; - - return (void *) (((unsigned long) ptr + agn) & ~agn); -} - -static struct dm_ioctl *_dm_ioctl_setup(struct devmapping *dm, int flags) -{ - void *buffer; - void *p; - const size_t min_size = 16 * 1024; - size_t len = sizeof(struct dm_ioctl); - struct dm_ioctl *io; - struct dm_target_spec *tgt; - int i; - char params[1024]; - char key[80]; - - key[0] = '\0'; - for (i = 0; i < (int) sizeof(dm->key); i++) { - char tmp[8]; - - sprintf(tmp, "%02x", dm->key[i]); - strcat(key, tmp); - } - - char srcdev[128]; - - // XXX: Handle non crypt targets and non twofish (use param) - if (dm->src_type == dmsrc_loopback) - strcpy(srcdev, dm->type_data.loop.loop_dev); - else if (dm->src_type == dmsrc_partition) - strcpy(srcdev, dm->type_data.part.part_dev); - - sprintf(params, "twofish %s 0 %s 0", key, srcdev); - -LOG_VOL("Params = '%s'", params); - - if (len < min_size) - len = min_size; - - if (!(buffer = malloc(len))) { - LOGE("out of memory"); - return NULL; - } - - memset(buffer, 0, len); - io = buffer; - tgt = (struct dm_target_spec *) &buffer[sizeof(struct dm_ioctl)]; - - io->version[0] = 4; - io->version[1] = 0; - io->version[2] = 0; - - io->data_size = len; - io->data_start = sizeof(struct dm_ioctl); - - io->flags = flags; - io->dev = 0; - - io->target_count = 1; - io->event_nr = 1; - strncpy(io->name, dm->target, sizeof(io->name)); - - tgt->status = 0; - tgt->sector_start = 0; - tgt->length = (dm->size_mb * (1024 * 1024)) / 512; - strncpy(tgt->target_type, "crypt", sizeof(tgt->target_type)); - - p = buffer + sizeof(struct dm_ioctl) + sizeof(struct dm_target_spec); - strcpy((char *) p, params); - p+= strlen(params) + 1; - - p = _align(p, 8); - tgt->next = p - buffer; - - return io; -} - -static int get_next_available_dm() -{ - int i; - - for (i = 0; i < 8; i++) { - char path[255]; - sprintf(path, "/dev/block/dm-%d", i); - if ((access(path, F_OK) < 0) && (errno == ENOENT)) - return i; - } - - LOGE("Out of device mapper numbers"); - return -1; -} - -static int create_devmapping(struct devmapping *dm) -{ - struct dm_ioctl *io; - int rc, fd; - -#if DEBUG_DEVMAPPER - LOG_VOL("create_devmapping():"); -#endif - - if (dm->dm_no < 0) { - LOGE("Invalid dm_no set"); - return -EINVAL; - } - - if ((fd = open("/dev/device-mapper", O_RDWR)) < 0) { - LOGE("Error opening device mapper (%d)", errno); - return -errno; - } - - if (!(io = _dm_ioctl_setup(dm, 0))) { - LOGE("Unable to setup ioctl (out of memory)"); - close(fd); - return -ENOMEM; - } - - if ((rc = ioctl(fd, DM_DEV_CREATE, io)) < 0) { - LOGE("device-mapper create ioctl failed (%d)", errno); - rc = -errno; - goto out_free; - } - - free(io); - - if (!(io = _dm_ioctl_setup(dm, DM_STATUS_TABLE_FLAG))) { - LOGE("Unable to setup ioctl (out of memory)"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(fd, DM_TABLE_LOAD, io)) < 0) { - LOGE("device-mapper load ioctl failed (%d)", errno); - rc = -errno; - goto out_free; - } - - free(io); - - if (!(io = _dm_ioctl_setup(dm, 0))) { - LOGE("Unable to setup ioctl (out of memory)"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(fd, DM_DEV_SUSPEND, io)) < 0) { - LOGE("device-mapper resume ioctl failed (%d)", errno); - rc = -errno; - goto out_free; - } - -out_free: - free (io); -out_nofree: - close (fd); - return rc; -} - -static int loopback_start(struct devmapping *dm) -{ - int i; - int fd; - char filename[255]; - int rc; - -#if DEBUG_DEVMAPPER - LOG_VOL("loopback_start(%s):", dm->type_data.loop.loop_src); -#endif - - for (i = 0; i < MAX_LOOP; i++) { - struct loop_info info; - - sprintf(filename, "/dev/block/loop%d", i); - - if ((fd = open(filename, O_RDWR)) < 0) { - LOGE("Unable to open %s (%s)", filename, strerror(errno)); - return -errno; - } - - rc = ioctl(fd, LOOP_GET_STATUS, &info); - if (rc < 0 && errno == ENXIO) - break; - - close(fd); - - if (rc < 0) { - LOGE("Unable to get loop status for %s (%s)", filename, - strerror(errno)); - return -errno; - } - } - - if (i == MAX_LOOP) { - LOGE("Out of loop devices"); - return -ENOSPC; - } - - int file_fd; - - if ((file_fd = open(dm->type_data.loop.loop_src, O_RDWR)) < 0) { - LOGE("Unable to open %s (%s)", dm->type_data.loop.loop_src, - strerror(errno)); - return -errno; - } - - if (ioctl(fd, LOOP_SET_FD, file_fd) < 0) { - LOGE("Error setting up loopback interface (%s)", strerror(errno)); - return -errno; - } - - dm->type_data.loop.loop_dev = strdup(filename); - dm->type_data.loop.loop_no = i; - - close(fd); - close(file_fd); - -#if DEBUG_DEVMAPPER - LOG_VOL("Loop setup on %s for %s", dm->type_data.loop.loop_dev, - dm->type_data.loop.loop_src); -#endif - - return 0; -} - -int devmapper_start(struct devmapping *dm) -{ - int rc; - char src_blkdev_path[255]; - -#if DEBUG_DEVMAPPER - LOG_VOL("devmapper_start()"); -#endif - - if (dm->src_type == dmsrc_loopback) { - if ((rc = loopback_start(dm)) < 0) - return rc; - } else if (dm->src_type == dmsrc_partition) { - LOGE("partition maps not yet supported"); - return -ENOSYS; - } else { - LOGE("devmapper_start(): Unsupported source type '%d'", dm->src_type); - return -ENOENT; - } - - /* - * Configure the device mapper - */ - if ((rc = create_devmapping(dm)) < 0) { - LOGE("Failed to create devmapping (%d)", rc); - // XXX: if loopback then tear down - return rc; - } - - return 0; -} - -struct devmapping *devmapper_init(char *src, char *src_type, uint32_t size_mb, - char *target, char *params, char *tgt_fs, char *mediapath) -{ - struct devmapping *dm; - - if (!(dm = malloc(sizeof(struct devmapping)))) { - LOGE("devmapper_init(): out of memory"); - return NULL; - } - - memset(dm, 0, sizeof(struct devmapping)); - - if (!strcmp(src_type, "loopback_file")) { - dm->src_type = dmsrc_loopback; - dm->type_data.loop.loop_src = strdup(src); - } else if (!strncmp(src_type, "partition ", strlen("partition "))) { - dm->src_type = dmsrc_partition; - char *p = strtok(src_type, " "); - if (!p) { - LOGE("Invalid partition specifier"); - goto out_free; - } - dm->type_data.part.part_type = strtoul(p, NULL, 0); - } else { - LOGE("Invalid src_type defined (%s)", src_type); - goto out_free; - } - - // XXX: Validate these - dm->size_mb = size_mb; - dm->target = strdup(target); - dm->params = strdup(params); - dm->tgt_fs = strdup(tgt_fs); - - if ((dm->dm_no = get_next_available_dm()) < 0) - goto out_free; - - sprintf(mediapath, "/devices/virtual/block/dm-%d", dm->dm_no); - - if (!(dm->media = media_create(mediapath, - "unknown", - "unknown", - media_devmapper))) { - LOGE("Unable to create media"); - goto out_free; - } - - return dm; - out_free: - if (dm->target) - free(dm->target); - if (dm->params) - free(dm->params); - if (dm->tgt_fs) - free(dm->tgt_fs); - - free(dm); - return NULL; -} - -int devmapper_genesis(struct devmapping *dm) -{ - - if (dm->src_type == dmsrc_loopback) { - int fd; - - LOG_VOL("devmapper_genesis(): Working on %s", - dm->type_data.loop.loop_src); - - unlink(dm->type_data.loop.loop_src); - - LOG_VOL("devmapper_genesis(): Creating imagefile (%u MB)", - dm->size_mb); - - if ((fd = creat(dm->type_data.loop.loop_src, 0600)) < 0) { - LOGE("Error creating imagefile (%s)", strerror(errno)); - return -errno; - } - - if (ftruncate(fd, (dm->size_mb * (1024 * 1024))) < 0) { - LOGE("Error truncating imagefile (%s)", strerror(errno)); - close(fd); - return -errno; - } - close(fd); - } else if (dm->src_type == dmsrc_partition) { - LOGE("partition maps not yet supported"); - return -ENOSYS; - } - - return devmapper_start(dm); -} - -static int destroy_devmapping(struct devmapping *dm) -{ - struct dm_ioctl *io; - int dmFd; - int rc = 0; - - LOG_VOL("destroy_devmapping():"); - - if ((dmFd = open("/dev/device-mapper", O_RDWR)) < 0) { - LOGE("Error opening device mapper (%d)", errno); - return -errno; - } - - if (!(io = _dm_ioctl_setup(dm, DM_PERSISTENT_DEV_FLAG))) { - LOGE("Unable to setup ioctl (out of memory)"); - rc = -ENOMEM; - goto out_nofree; - } - - if ((rc = ioctl(dmFd, DM_DEV_REMOVE, io)) < 0) { - LOGE("device-mapper remove ioctl failed (%d)", errno); - rc = -errno; - goto out_free; - } - -out_free: - free (io); -out_nofree: - close (dmFd); - return rc; -} - -static int loopback_stop(struct devmapping *dm) -{ - char devname[255]; - int device_fd; - int rc = 0; - - LOG_VOL("loopback_stop():"); - - device_fd = open(dm->type_data.loop.loop_dev, O_RDONLY); - if (device_fd < 0) { - LOG_ERROR("Failed to open loop (%d)", errno); - return -errno; - } - - if (ioctl(device_fd, LOOP_CLR_FD, 0) < 0) { - LOG_ERROR("Failed to destroy loop (%d)", errno); - rc = -errno; - } - - close(device_fd); - return rc; -} - -int devmapper_stop(struct devmapping *dm) -{ - int rc; - - LOG_VOL("devmapper_stop():"); - - if ((rc = destroy_devmapping(dm))) - return rc; - - if (dm->src_type == dmsrc_loopback) { - if ((rc = loopback_stop(dm))) - return rc; - } else if (dm->src_type == dmsrc_partition) { - LOGE("partition maps not yet supported"); - return -ENOSYS; - } - return 0; -} diff --git a/vold/devmapper.h b/vold/devmapper.h deleted file mode 100644 index 3d8cab365eee0fac1cc8b45686dd7dfcbd188414..0000000000000000000000000000000000000000 --- a/vold/devmapper.h +++ /dev/null @@ -1,70 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _DEVMAPPER_H -#define _DEVMAPPER_H - -#include <pthread.h> - -#include "vold.h" -#include "blkdev.h" -#include "media.h" - -#define MAX_LOOP 8 - -enum dm_src_type { - dmsrc_unknown, - dmsrc_loopback, - dmsrc_partition, -}; - -struct loop_data { - char *loop_src; - - char *loop_dev; - int loop_no; -}; - -struct part_data { - char part_type; - - char *part_dev; -}; - -struct devmapping { - enum dm_src_type src_type; - union { - struct loop_data loop; - struct part_data part; - } type_data; - - uint32_t size_mb; - char *target; - char *params; - char *tgt_fs; - - unsigned char key[16]; - int dm_no; - - media_t *media; -}; - -struct devmapping *devmapper_init(char *, char *, unsigned int, char *, char *, char *, char *); -int devmapper_start(struct devmapping *); -int devmapper_stop(struct devmapping *); -int devmapper_genesis(struct devmapping *); -#endif diff --git a/vold/diskmbr.h b/vold/diskmbr.h deleted file mode 100644 index 417e7cafca79f78e85b375ab6f5c95592dd67a9e..0000000000000000000000000000000000000000 --- a/vold/diskmbr.h +++ /dev/null @@ -1,75 +0,0 @@ -/*- - * Copyright (c) 1987, 1988, 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. - * - * @(#)disklabel.h 8.2 (Berkeley) 7/10/94 - * $FreeBSD: src/sys/sys/diskmbr.h,v 1.99.2.1 2005/01/31 23:26:56 imp Exp $ - */ - -#ifndef _SYS_DISKMBR_H_ -#define _SYS_DISKMBR_H_ - -#define DOSBBSECTOR 0 /* DOS boot block relative sector number */ -#define DOSPARTOFF 446 -#define DOSPARTSIZE 16 -#define NDOSPART 4 -#define NEXTDOSPART 32 -#define DOSMAGICOFFSET 510 -#define DOSMAGIC 0xAA55 - -#define DOSPTYP_386BSD 0xa5 /* 386BSD partition type */ -#define DOSPTYP_LINSWP 0x82 /* Linux swap partition */ -#define DOSPTYP_LINUX 0x83 /* Linux partition */ -#define DOSPTYP_PMBR 0xee /* GPT Protective MBR */ -#define DOSPTYP_EXT 5 /* DOS extended partition */ -#define DOSPTYP_EXTLBA 15 /* DOS extended partition */ - -struct dos_partition { - unsigned char dp_flag; /* bootstrap flags */ - unsigned char dp_shd; /* starting head */ - unsigned char dp_ssect; /* starting sector */ - unsigned char dp_scyl; /* starting cylinder */ - unsigned char dp_typ; /* partition type */ - unsigned char dp_ehd; /* end head */ - unsigned char dp_esect; /* end sector */ - unsigned char dp_ecyl; /* end cylinder */ - u_int32_t dp_start; /* absolute starting sector number */ - u_int32_t dp_size; /* partition size in sectors */ -}; -#ifdef CTASSERT -CTASSERT(sizeof (struct dos_partition) == DOSPARTSIZE); -#endif - -void dos_partition_dec(void const *pp, struct dos_partition *d); -void dos_partition_enc(void *pp, struct dos_partition *d); - -#define DPSECT(s) ((s) & 0x3f) /* isolate relevant bits of sector */ -#define DPCYL(c, s) ((c) + (((s) & 0xc0)<<2)) /* and those that are cylinder */ - -#define DIOCSMBR _IOW('M', 129, u_char[512]) - -#endif /* !_SYS_DISKMBR_H_ */ diff --git a/vold/format.c b/vold/format.c deleted file mode 100755 index dd0515cf7423fc93a0e6e462cb2f0845f297b142..0000000000000000000000000000000000000000 --- a/vold/format.c +++ /dev/null @@ -1,113 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fcntl.h> -#include <errno.h> - -#include <linux/fs.h> - -#include "vold.h" -#include "blkdev.h" -#include "format.h" -#include "diskmbr.h" -#include "logwrapper.h" - -static char MKDOSFS_PATH[] = "/system/bin/mkdosfs"; -static char MKE2FS_PATH[] = "/system/bin/mke2fs"; - -int format_partition(blkdev_t *part, char *type) -{ - char *devpath; - int rc = -EINVAL; - - devpath = blkdev_get_devpath(part); - - if (!strcmp(type, FORMAT_TYPE_FAT32)) { - char *args[7]; - args[0] = MKDOSFS_PATH; - args[1] = "-F 32"; - args[2] = "-c 32"; - args[3] = "-n 2"; - args[4] = "-O android"; - args[5] = devpath; - args[6] = NULL; - rc = logwrap(6, args); - } else { - char *args[7]; - args[0] = MKE2FS_PATH; - args[1] = "-b 4096"; - args[2] = "-m 1"; - args[3] = "-L android"; - args[4] = "-v"; - args[5] = devpath; - args[6] = NULL; - rc = logwrap(6, args); - } - - free(devpath); - - if (rc == 0) { - LOG_VOL("Filesystem formatted OK"); - return 0; - } else { - LOGE("Format failed (unknokwn exit code %d)", rc); - return -EIO; - } - return 0; -} - -int initialize_mbr(blkdev_t *disk) -{ - int fd, rc; - unsigned char block[512]; - struct dos_partition part; - char *devpath; - - devpath = blkdev_get_devpath(disk); - - memset(&part, 0, sizeof(part)); - part.dp_flag = 0x80; - part.dp_typ = 0xc; - part.dp_start = ((1024 * 64) / 512) + 1; - part.dp_size = disk->nr_sec - part.dp_start; - - memset(block, 0, sizeof(block)); - block[0x1fe] = 0x55; - block[0x1ff] = 0xaa; - - dos_partition_enc(block + DOSPARTOFF, &part); - - if ((fd = open(devpath, O_RDWR)) < 0) { - LOGE("Error opening disk file (%s)", strerror(errno)); - return -errno; - } - free(devpath); - - if (write(fd, block, sizeof(block)) < 0) { - LOGE("Error writing MBR (%s)", strerror(errno)); - close(fd); - return -errno; - } - - if (ioctl(fd, BLKRRPART, NULL) < 0) { - LOGE("Error re-reading partition table (%s)", strerror(errno)); - close(fd); - return -errno; - } - close(fd); - return 0; -} diff --git a/vold/format.h b/vold/format.h deleted file mode 100644 index 73cc0126a18fd1c111d9aafa61498b1c4d48fb15..0000000000000000000000000000000000000000 --- a/vold/format.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _FORMAT_H -#define _FORMAT_H - -#define FORMAT_TYPE_EXT2 "ext2" -#define FORMAT_TYPE_FAT32 "fat32" - -int format_partition(blkdev_t *part, char *type); -int initialize_mbr(blkdev_t *disk); -#endif diff --git a/vold/geom_mbr_enc.c b/vold/geom_mbr_enc.c deleted file mode 100644 index f1f8339b7c00cd681d9bf9ee1a29876b8eccf303..0000000000000000000000000000000000000000 --- a/vold/geom_mbr_enc.c +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * Copyright (c) 2003 Poul-Henning Kamp - * 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. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - */ - -/* Functions to encode or decode struct dos_partition into a bytestream - * of correct endianess and packing. These functions do no validation - * or sanity checking, they only pack/unpack the fields correctly. - * - * NB! This file must be usable both in kernel and userland. - */ - -#include <sys/types.h> -#include <sys/endian.h> - -#include "diskmbr.h" - -static __inline uint32_t __unused -le32dec(const void *buf) -{ - const uint8_t *p = (const uint8_t *)buf; - - return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | p[0]); -} - -static __inline void -le32enc(void *pp, uint32_t u) -{ - unsigned char *p = (unsigned char *)pp; - - p[0] = u & 0xff; - p[1] = (u >> 8) & 0xff; - p[2] = (u >> 16) & 0xff; - p[3] = (u >> 24) & 0xff; -} - -void -dos_partition_dec(void const *pp, struct dos_partition *d) -{ - unsigned char const *p = pp; - - d->dp_flag = p[0]; - d->dp_shd = p[1]; - d->dp_ssect = p[2]; - d->dp_scyl = p[3]; - d->dp_typ = p[4]; - d->dp_ehd = p[5]; - d->dp_esect = p[6]; - d->dp_ecyl = p[7]; - d->dp_start = le32dec(p + 8); - d->dp_size = le32dec(p + 12); -} - -void -dos_partition_enc(void *pp, struct dos_partition *d) -{ - unsigned char *p = pp; - - p[0] = d->dp_flag; - p[1] = d->dp_shd; - p[2] = d->dp_ssect; - p[3] = d->dp_scyl; - p[4] = d->dp_typ; - p[5] = d->dp_ehd; - p[6] = d->dp_esect; - p[7] = d->dp_ecyl; - le32enc(p + 8, d->dp_start); - le32enc(p + 12, d->dp_size); -} diff --git a/vold/logwrapper.c b/vold/logwrapper.c deleted file mode 100644 index 25d22819b8505267f835489c149d72960fe240d2..0000000000000000000000000000000000000000 --- a/vold/logwrapper.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <errno.h> -#include <fcntl.h> - -#include "private/android_filesystem_config.h" -#include "cutils/log.h" - -int parent(const char *tag, int parent_read) { - int status; - char buffer[4096]; - - int a = 0; // start index of unprocessed data - int b = 0; // end index of unprocessed data - int sz; - while ((sz = read(parent_read, &buffer[b], sizeof(buffer) - 1 - b)) > 0) { - - sz += b; - // Log one line at a time - for (b = 0; b < sz; b++) { - if (buffer[b] == '\r') { - buffer[b] = '\0'; - } else if (buffer[b] == '\n') { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - a = b + 1; - } - } - - if (a == 0 && b == sizeof(buffer) - 1) { - // buffer is full, flush - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - b = 0; - } else if (a != b) { - // Keep left-overs - b -= a; - memmove(buffer, &buffer[a], b); - a = 0; - } else { - a = 0; - b = 0; - } - - } - // Flush remaining data - if (a != b) { - buffer[b] = '\0'; - LOG(LOG_INFO, tag, &buffer[a]); - } - status = 0xAAAA; - if (wait(&status) != -1) { // Wait for child - if (WIFEXITED(status)) { - LOG(LOG_INFO, "logwrapper", "%s terminated by exit(%d)", tag, - WEXITSTATUS(status)); - return WEXITSTATUS(status); - } else if (WIFSIGNALED(status)) - LOG(LOG_INFO, "logwrapper", "%s terminated by signal %d", tag, - WTERMSIG(status)); - else if (WIFSTOPPED(status)) - LOG(LOG_INFO, "logwrapper", "%s stopped by signal %d", tag, - WSTOPSIG(status)); - } else - LOG(LOG_INFO, "logwrapper", "%s wait() failed: %s (%d)", tag, - strerror(errno), errno); - return -EAGAIN; -} - -void child(int argc, char* argv[]) { - // create null terminated argv_child array - char* argv_child[argc + 1]; - memcpy(argv_child, argv, argc * sizeof(char *)); - argv_child[argc] = NULL; - - // XXX: PROTECT FROM VIKING KILLER - if (execvp(argv_child[0], argv_child)) { - LOG(LOG_ERROR, "logwrapper", - "executing %s failed: %s", argv_child[0], strerror(errno)); - exit(-1); - } -} - -int logwrap(int argc, char* argv[], pid_t *childPid) -{ - pid_t pid; - - int parent_ptty; - int child_ptty; - char *child_devname = NULL; - - /* Use ptty instead of socketpair so that STDOUT is not buffered */ - parent_ptty = open("/dev/ptmx", O_RDWR); - if (parent_ptty < 0) { - LOG(LOG_ERROR, "logwrapper", "Cannot create parent ptty"); - return -errno; - } - - if (grantpt(parent_ptty) || unlockpt(parent_ptty) || - ((child_devname = (char*)ptsname(parent_ptty)) == 0)) { - LOG(LOG_ERROR, "logwrapper", "Problem with /dev/ptmx"); - return -1; - } - - pid = fork(); - if (pid < 0) { - LOG(LOG_ERROR, "logwrapper", "Failed to fork"); - return -errno; - } else if (pid == 0) { - child_ptty = open(child_devname, O_RDWR); - if (child_ptty < 0) { - LOG(LOG_ERROR, "logwrapper", "Problem with child ptty"); - return -errno; - } - - // redirect stdout and stderr - close(parent_ptty); - dup2(child_ptty, 1); - dup2(child_ptty, 2); - close(child_ptty); - - child(argc, argv); - } else { - return parent(argv[0], parent_ptty); - } - - return 0; -} diff --git a/vold/logwrapper.h b/vold/logwrapper.h deleted file mode 100644 index 602e24cb2087f3e0e62f8e2c4f09a891a43926e2..0000000000000000000000000000000000000000 --- a/vold/logwrapper.h +++ /dev/null @@ -1,23 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LOGWRAPPER_H -#define _LOGWRAPPER_H - -#include <stdlib.h> -int logwrap(int argc, char* argv[]); -#endif diff --git a/vold/media.c b/vold/media.c deleted file mode 100644 index 40637ff9eead5d7e1c1697225d5d6c9be5ef6d0e..0000000000000000000000000000000000000000 --- a/vold/media.c +++ /dev/null @@ -1,165 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> - -#include <sys/types.h> - -#include "vold.h" -#include "media.h" - -static media_list_t *list_root = NULL; - -media_t *media_create(char *devpath, char *name, char *serial, media_type_t type) -{ - media_list_t *list_entry; - media_t *new; - - if (!(new = malloc(sizeof(media_t)))) - return NULL; - - memset(new, 0, sizeof(media_t)); - - if (!(list_entry = malloc(sizeof(media_list_t)))) { - free(new); - return NULL; - } - list_entry->media = new; - list_entry->next = NULL; - - if (!list_root) - list_root = list_entry; - else { - media_list_t *list_scan = list_root; - while(list_scan->next) - list_scan = list_scan->next; - list_scan->next = list_entry; - } - - new->devpath = strdup(devpath); - new->name = strdup(name); - if (!serial) - new->serial = 0; - else - new->serial = strtoul(serial, NULL, 0); - - new->media_type = type; - - return new; -} - -void media_destroy(media_t *media) -{ - media_list_t *list_next; - - if (list_root->media == media) { - list_next = list_root->next; - free(list_root); - list_root = list_next; - } else { - media_list_t *list_scan = list_root; - while (list_scan->next->media != media) - list_scan = list_scan -> next; - list_next = list_scan->next->next; - free(list_scan->next); - list_scan->next = list_next; - } - - free(media->devpath); - free(media->name); - - while(media->devs) - media_remove_blkdev(media, media->devs->dev); - free(media); -} - -media_t *media_lookup_by_path(char *devpath, boolean fuzzy_match) -{ - media_list_t *list_scan = list_root; - - while (list_scan) { - if (fuzzy_match) { - if (!strncmp(list_scan->media->devpath, devpath, strlen(devpath))) - return list_scan->media; - } else { - if (!strcmp(list_scan->media->devpath, devpath)) - return list_scan->media; - } - list_scan = list_scan->next; - } -#if DEBUG_MEDIA - LOG_VOL("media_lookup_by_path(): No media found @ %s", devpath); -#endif - return NULL; -} - -int media_add_blkdev(media_t *card, blkdev_t *dev) -{ - blkdev_list_t *list_entry; - - if (!(list_entry = malloc(sizeof(blkdev_list_t)))) { - LOGE("Out of memory"); - return -ENOMEM; - } - - list_entry->next = NULL; - list_entry->dev = dev; - if (!card->devs) - card->devs = list_entry; - else { - blkdev_list_t *scan = card->devs; - - while(scan->next) - scan = scan->next; - - scan->next = list_entry; - } - return 0; -} - -void media_remove_blkdev(media_t *card, blkdev_t *dev) -{ - if (card->devs->dev == dev) - card->devs = card->devs->next; - else { - blkdev_list_t *scan = card->devs; - while (scan->next->dev != dev) - scan = scan -> next; - blkdev_list_t *next = scan->next->next; - free(scan->next); - scan->next = next; - } -} - -media_t *media_lookup_by_dev(blkdev_t *dev) -{ - media_list_t *media_scan = list_root; - - while (media_scan) { - blkdev_list_t *blk_scan = media_scan->media->devs; - while (blk_scan) { - if (blk_scan->dev == dev) - return media_scan->media; - blk_scan = blk_scan->next; - } - media_scan = media_scan->next; - } - return NULL; -} diff --git a/vold/media.h b/vold/media.h deleted file mode 100644 index 567ce045138b390a898a830ebe3a39c2ccbc2247..0000000000000000000000000000000000000000 --- a/vold/media.h +++ /dev/null @@ -1,51 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _MEDIA_H -#define _MEDIA_H - -#include <sys/types.h> - -#include "blkdev.h" - -typedef enum media_type { - media_unknown, - media_mmc, - media_devmapper, -} media_type_t; - -typedef struct media { - char *devpath; - char *name; - uint32_t serial; - media_type_t media_type; - - blkdev_list_t *devs; -} media_t; - -typedef struct media_list { - media_t *media; - struct media_list *next; -} media_list_t; - -media_t *media_create(char *devpath, char *name, char *serial, enum media_type); -media_t *media_lookup_by_path(char *devpath, boolean fuzzy_match); -media_t *media_lookup_by_dev(blkdev_t *dev); -void media_destroy(media_t *media); -int media_add_blkdev(media_t *media, blkdev_t *dev); -void media_remove_blkdev(media_t *media, blkdev_t *dev); -#endif diff --git a/vold/misc.c b/vold/misc.c deleted file mode 100644 index 951414c63d7d77e4b246edcc740ba6015871659a..0000000000000000000000000000000000000000 --- a/vold/misc.c +++ /dev/null @@ -1,91 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdio.h> -#include <string.h> -#include <fcntl.h> -#include <unistd.h> -#include <malloc.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> - -void *read_file(char *filename, ssize_t *_size) -{ - int ret, fd; - struct stat sb; - ssize_t size; - void *buffer = NULL; - - /* open the file */ - fd = open(filename, O_RDONLY); - if (fd < 0) - return NULL; - - /* find out how big it is */ - if (fstat(fd, &sb) < 0) - goto bail; - size = sb.st_size; - - /* allocate memory for it to be read into */ - buffer = malloc(size); - if (!buffer) - goto bail; - - /* slurp it into our buffer */ - ret = read(fd, buffer, size); - if (ret != size) - goto bail; - - /* let the caller know how big it is */ - *_size = size; - -bail: - close(fd); - return buffer; -} -char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer) -{ - int i; - - strcpy(buffer, path); - - for (i = 0; i < num_elements_to_remove; i++) { - char *p = &buffer[strlen(buffer)-1]; - - for (p = &buffer[strlen(buffer) -1]; *p != '/'; p--); - *p = '\0'; - } - - return buffer; -} - -char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var) -{ - char filename[255]; - char *p; - ssize_t sz; - - sprintf(filename, "/sys%s/%s", devpath, var); - p = read_file(filename, &sz); - p[(strlen(p) - 1)] = '\0'; - strncpy(buffer, p, maxlen); - free(p); - return buffer; -} - diff --git a/vold/mmc.c b/vold/mmc.c deleted file mode 100644 index 0f08964b3521c1af2efcfd642cb5e5deb8082386..0000000000000000000000000000000000000000 --- a/vold/mmc.c +++ /dev/null @@ -1,293 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> - -#include <sys/types.h> - -#include "vold.h" -#include "mmc.h" -#include "media.h" - -#define DEBUG_BOOTSTRAP 0 - -static int mmc_bootstrap_controller(char *sysfs_path); -static int mmc_bootstrap_card(char *sysfs_path); -static int mmc_bootstrap_block(char *devpath); -static int mmc_bootstrap_mmcblk(char *devpath); -static int mmc_bootstrap_mmcblk_partition(char *devpath); - -/* - * Bootstrap our mmc information. - */ -int mmc_bootstrap() -{ - DIR *d; - struct dirent *de; - - if (!(d = opendir(SYSFS_CLASS_MMC_PATH))) { - LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_MMC_PATH); - return -errno; - } - - while ((de = readdir(d))) { - char tmp[255]; - - if (de->d_name[0] == '.') - continue; - - sprintf(tmp, "%s/%s", SYSFS_CLASS_MMC_PATH, de->d_name); - if (mmc_bootstrap_controller(tmp)) - LOG_ERROR("Error bootstrapping controller '%s' (%m)", tmp); - } - - closedir(d); - - return 0; -} - -static int mmc_bootstrap_controller(char *sysfs_path) -{ - DIR *d; - struct dirent *de; - -#if DEBUG_BOOTSTRAP - LOG_VOL("bootstrap_controller(%s):", sysfs_path); -#endif - if (!(d = opendir(sysfs_path))) { - LOG_ERROR("Unable to open '%s' (%m)", sysfs_path); - return -errno; - } - - while ((de = readdir(d))) { - char tmp[255]; - - if (de->d_name[0] == '.') - continue; - - if ((!strcmp(de->d_name, "uevent")) || - (!strcmp(de->d_name, "subsystem")) || - (!strcmp(de->d_name, "device")) || - (!strcmp(de->d_name, "power"))) { - continue; - } - - sprintf(tmp, "%s/%s", sysfs_path, de->d_name); - - if (mmc_bootstrap_card(tmp) < 0) - LOG_ERROR("Error bootstrapping card '%s' (%m)", tmp); - } // while - - closedir(d); - return 0; -} - -static int mmc_bootstrap_card(char *sysfs_path) -{ - char saved_cwd[255]; - char new_cwd[255]; - char *devpath; - char *uevent_params[4]; - char *p; - char filename[255]; - char tmp[255]; - ssize_t sz; - -#if DEBUG_BOOTSTRAP - LOG_VOL("bootstrap_card(%s):", sysfs_path); -#endif - - /* - * sysfs_path is based on /sys/class, but we want the actual device class - */ - if (!getcwd(saved_cwd, sizeof(saved_cwd))) { - LOGE("Error getting working dir path"); - return -errno; - } - - if (chdir(sysfs_path) < 0) { - LOGE("Unable to chdir to %s (%m)", sysfs_path); - return -errno; - } - - if (!getcwd(new_cwd, sizeof(new_cwd))) { - LOGE("Buffer too small for device path"); - return -errno; - } - - if (chdir(saved_cwd) < 0) { - LOGE("Unable to restore working dir"); - return -errno; - } - - devpath = &new_cwd[4]; // Skip over '/sys' - - /* - * Collect parameters so we can simulate a UEVENT - */ - sprintf(tmp, "DEVPATH=%s", devpath); - uevent_params[0] = (char *) strdup(tmp); - - sprintf(filename, "/sys%s/type", devpath); - p = read_file(filename, &sz); - p[strlen(p) - 1] = '\0'; - sprintf(tmp, "MMC_TYPE=%s", p); - free(p); - uevent_params[1] = (char *) strdup(tmp); - - sprintf(filename, "/sys%s/name", devpath); - p = read_file(filename, &sz); - p[strlen(p) - 1] = '\0'; - sprintf(tmp, "MMC_NAME=%s", p); - free(p); - uevent_params[2] = (char *) strdup(tmp); - - uevent_params[3] = (char *) NULL; - - if (simulate_uevent("mmc", devpath, "add", uevent_params) < 0) { - LOGE("Error simulating uevent (%m)"); - return -errno; - } - - /* - * Check for block drivers - */ - char block_devpath[255]; - sprintf(tmp, "%s/block", devpath); - sprintf(filename, "/sys%s/block", devpath); - if (!access(filename, F_OK)) { - if (mmc_bootstrap_block(tmp)) { - LOGE("Error bootstrapping block @ %s", tmp); - } - } - - return 0; -} - -static int mmc_bootstrap_block(char *devpath) -{ - char blockdir_path[255]; - DIR *d; - struct dirent *de; - -#if DEBUG_BOOTSTRAP - LOG_VOL("mmc_bootstrap_block(%s):", devpath); -#endif - - sprintf(blockdir_path, "/sys%s", devpath); - - if (!(d = opendir(blockdir_path))) { - LOGE("Failed to opendir %s", devpath); - return -errno; - } - - while ((de = readdir(d))) { - char tmp[255]; - - if (de->d_name[0] == '.') - continue; - sprintf(tmp, "%s/%s", devpath, de->d_name); - if (mmc_bootstrap_mmcblk(tmp)) - LOGE("Error bootstraping mmcblk @ %s", tmp); - } - closedir(d); - return 0; -} - -static int mmc_bootstrap_mmcblk(char *devpath) -{ - char *mmcblk_devname; - int part_no; - int rc; - -#if DEBUG_BOOTSTRAP - LOG_VOL("mmc_bootstrap_mmcblk(%s):", devpath); -#endif - - if ((rc = mmc_bootstrap_mmcblk_partition(devpath))) { - LOGE("Error bootstrapping mmcblk partition '%s'", devpath); - return rc; - } - - for (mmcblk_devname = &devpath[strlen(devpath)]; - *mmcblk_devname != '/'; mmcblk_devname--); - mmcblk_devname++; - - for (part_no = 0; part_no < 4; part_no++) { - char part_file[255]; - sprintf(part_file, "/sys%s/%sp%d", devpath, mmcblk_devname, part_no); - if (!access(part_file, F_OK)) { - char part_devpath[255]; - - sprintf(part_devpath, "%s/%sp%d", devpath, mmcblk_devname, part_no); - if (mmc_bootstrap_mmcblk_partition(part_devpath)) - LOGE("Error bootstrapping mmcblk partition '%s'", part_devpath); - } - } - - return 0; -} - -static int mmc_bootstrap_mmcblk_partition(char *devpath) -{ - char filename[255]; - char *uevent_buffer; - ssize_t sz; - char *uevent_params[4]; - char tmp[255]; - FILE *fp; - char line[255]; - -#if DEBUG_BOOTSTRAP - LOG_VOL("mmc_bootstrap_mmcblk_partition(%s):", devpath); -#endif - - sprintf(tmp, "DEVPATH=%s", devpath); - uevent_params[0] = strdup(tmp); - - sprintf(filename, "/sys%s/uevent", devpath); - if (!(fp = fopen(filename, "r"))) { - LOGE("Unable to open '%s' (%m)", filename); - return -errno; - } - - while (fgets(line, sizeof(line), fp)) { - line[strlen(line)-1] = 0; - if (!strncmp(line, "DEVTYPE=", 8)) - uevent_params[1] = strdup(line); - else if (!strncmp(line, "MAJOR=",6)) - uevent_params[2] = strdup(line); - else if (!strncmp(line, "MINOR=",6)) - uevent_params[3] = strdup(line); - } - fclose(fp); - - if (!uevent_params[1] || !uevent_params[2] || !uevent_params[3]) { - LOGE("mmcblk uevent missing required params"); - return -1; - } - uevent_params[4] = '\0'; - - if (simulate_uevent("block", devpath, "add", uevent_params) < 0) { - LOGE("Error simulating uevent (%m)"); - return -errno; - } - return 0; -} diff --git a/vold/mmc.h b/vold/mmc.h deleted file mode 100644 index 5a5d184ed56e06abb2cb5dcc2aee8a50d5671b23..0000000000000000000000000000000000000000 --- a/vold/mmc.h +++ /dev/null @@ -1,23 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _MMC_H -#define _MMC_H - -#define SYSFS_CLASS_MMC_PATH "/sys/class/mmc_host" - -#endif diff --git a/vold/switch.c b/vold/switch.c deleted file mode 100644 index ba9ddb390cf163def4de81f65e937d7c29991c2c..0000000000000000000000000000000000000000 --- a/vold/switch.c +++ /dev/null @@ -1,121 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <dirent.h> -#include <errno.h> - -#include <sys/types.h> - -#include "vold.h" -#include "switch.h" - -#define DEBUG_BOOTSTRAP 0 - -static int mmc_bootstrap_switch(char *sysfs_path); - -int switch_bootstrap() -{ - DIR *d; - struct dirent *de; - - if (!(d = opendir(SYSFS_CLASS_SWITCH_PATH))) { - LOG_ERROR("Unable to open '%s' (%m)", SYSFS_CLASS_SWITCH_PATH); - return -errno; - } - - while ((de = readdir(d))) { - char tmp[255]; - - if (de->d_name[0] == '.') - continue; - - sprintf(tmp, "%s/%s", SYSFS_CLASS_SWITCH_PATH, de->d_name); - if (mmc_bootstrap_switch(tmp)) - LOG_ERROR("Error bootstrapping switch '%s' (%m)", tmp); - } - - closedir(d); - - return 0; -} - -static int mmc_bootstrap_switch(char *sysfs_path) -{ -#if DEBUG_BOOTSTRAP - LOG_VOL("bootstrap_switch(%s):", sysfs_path); -#endif - - char filename[255]; - char name[255]; - char state[255]; - char tmp[255]; - char *uevent_params[3]; - char devpath[255]; - FILE *fp; - - /* - * Read switch name - */ - sprintf(filename, "%s/name", sysfs_path); - if (!(fp = fopen(filename, "r"))) { - LOGE("Error opening switch name path '%s' (%s)", - sysfs_path, strerror(errno)); - return -errno; - } - if (!fgets(name, sizeof(name), fp)) { - LOGE("Unable to read switch name"); - fclose(fp); - return -EIO; - } - fclose(fp); - - name[strlen(name) -1] = '\0'; - sprintf(devpath, "/devices/virtual/switch/%s", name); - sprintf(tmp, "SWITCH_NAME=%s", name); - uevent_params[0] = (char *) strdup(tmp); - - /* - * Read switch state - */ - sprintf(filename, "%s/state", sysfs_path); - if (!(fp = fopen(filename, "r"))) { - LOGE("Error opening switch state path '%s' (%s)", - sysfs_path, strerror(errno)); - return -errno; - } - if (!fgets(state, sizeof(state), fp)) { - LOGE("Unable to read switch state"); - fclose(fp); - return -EIO; - } - fclose(fp); - - state[strlen(state) -1] = '\0'; - sprintf(tmp, "SWITCH_STATE=%s", state); - uevent_params[1] = (char *) strdup(tmp); - - uevent_params[2] = (char *) NULL; - - if (simulate_uevent("switch", devpath, "add", uevent_params) < 0) { - LOGE("Error simulating uevent (%s)", strerror(errno)); - return -errno; - } - - return 0; -} diff --git a/vold/switch.h b/vold/switch.h deleted file mode 100644 index 6729f2df7befd2369f8dd6f7e36ff1ff8e5f7e92..0000000000000000000000000000000000000000 --- a/vold/switch.h +++ /dev/null @@ -1,25 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _SWITCH_H -#define _SWITCH_H - -#include "vold.h" - -#define SYSFS_CLASS_SWITCH_PATH "/sys/class/switch" - -#endif diff --git a/vold/uevent.c b/vold/uevent.c deleted file mode 100644 index b1a69444ecf96ed32cbbe52eda238b906a0ee85e..0000000000000000000000000000000000000000 --- a/vold/uevent.c +++ /dev/null @@ -1,443 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <string.h> -#include <stdlib.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/socket.h> - -#include "vold.h" -#include "uevent.h" -#include "mmc.h" -#include "blkdev.h" -#include "volmgr.h" -#include "media.h" - -#define DEBUG_UEVENT 0 - -#define UEVENT_PARAMS_MAX 32 - -enum uevent_action { action_add, action_remove, action_change }; - -struct uevent { - char *path; - enum uevent_action action; - char *subsystem; - char *param[UEVENT_PARAMS_MAX]; - unsigned int seqnum; -}; - -struct uevent_dispatch { - char *subsystem; - int (* dispatch) (struct uevent *); -}; - -static void dump_uevent(struct uevent *); -static int dispatch_uevent(struct uevent *event); -static void free_uevent(struct uevent *event); -static char *get_uevent_param(struct uevent *event, char *param_name); - -static int handle_powersupply_event(struct uevent *event); -static int handle_switch_event(struct uevent *); -static int handle_battery_event(struct uevent *); -static int handle_mmc_event(struct uevent *); -static int handle_block_event(struct uevent *); -static int handle_bdi_event(struct uevent *); -static void _cb_blkdev_ok_to_destroy(blkdev_t *dev); - -static struct uevent_dispatch dispatch_table[] = { - { "switch", handle_switch_event }, - { "battery", handle_battery_event }, - { "mmc", handle_mmc_event }, - { "block", handle_block_event }, - { "bdi", handle_bdi_event }, - { "power_supply", handle_powersupply_event }, - { NULL, NULL } -}; - -static boolean low_batt = false; -static boolean door_open = true; - -int process_uevent_message(int socket) -{ - char buffer[64 * 1024]; // Thank god we're not in the kernel :) - int count; - char *s = buffer; - char *end; - struct uevent *event; - int param_idx = 0; - int i; - int first = 1; - int rc = 0; - - if ((count = recv(socket, buffer, sizeof(buffer), 0)) < 0) { - LOGE("Error receiving uevent (%s)", strerror(errno)); - return -errno; - } - - if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)", strerror(errno)); - return -errno; - } - - memset(event, 0, sizeof(struct uevent)); - - end = s + count; - while (s < end) { - if (first) { - char *p; - for (p = s; *p != '@'; p++); - p++; - event->path = strdup(p); - first = 0; - } else { - if (!strncmp(s, "ACTION=", strlen("ACTION="))) { - char *a = s + strlen("ACTION="); - - if (!strcmp(a, "add")) - event->action = action_add; - else if (!strcmp(a, "change")) - event->action = action_change; - else if (!strcmp(a, "remove")) - event->action = action_remove; - } else if (!strncmp(s, "SEQNUM=", strlen("SEQNUM="))) - event->seqnum = atoi(s + strlen("SEQNUM=")); - else if (!strncmp(s, "SUBSYSTEM=", strlen("SUBSYSTEM="))) - event->subsystem = strdup(s + strlen("SUBSYSTEM=")); - else - event->param[param_idx++] = strdup(s); - } - s+= strlen(s) + 1; - } - - rc = dispatch_uevent(event); - - free_uevent(event); - return rc; -} - -int simulate_uevent(char *subsys, char *path, char *action, char **params) -{ - struct uevent *event; - char tmp[255]; - int i, rc; - - if (!(event = malloc(sizeof(struct uevent)))) { - LOGE("Error allocating memory (%s)", strerror(errno)); - return -errno; - } - - memset(event, 0, sizeof(struct uevent)); - - event->subsystem = strdup(subsys); - - if (!strcmp(action, "add")) - event->action = action_add; - else if (!strcmp(action, "change")) - event->action = action_change; - else if (!strcmp(action, "remove")) - event->action = action_remove; - else { - LOGE("Invalid action '%s'", action); - return -1; - } - - event->path = strdup(path); - - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!params[i]) - break; - event->param[i] = strdup(params[i]); - } - - rc = dispatch_uevent(event); - free_uevent(event); - return rc; -} - -static int dispatch_uevent(struct uevent *event) -{ - int i; - -#if DEBUG_UEVENT - dump_uevent(event); -#endif - for (i = 0; dispatch_table[i].subsystem != NULL; i++) { - if (!strcmp(dispatch_table[i].subsystem, event->subsystem)) - return dispatch_table[i].dispatch(event); - } - -#if DEBUG_UEVENT - LOG_VOL("No uevent handlers registered for '%s' subsystem", event->subsystem); -#endif - return 0; -} - -static void dump_uevent(struct uevent *event) -{ - int i; - - LOG_VOL("[UEVENT] Sq: %u S: %s A: %d P: %s", - event->seqnum, event->subsystem, event->action, event->path); - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!event->param[i]) - break; - LOG_VOL("%s", event->param[i]); - } -} - -static void free_uevent(struct uevent *event) -{ - int i; - free(event->path); - free(event->subsystem); - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!event->param[i]) - break; - free(event->param[i]); - } - free(event); -} - -static char *get_uevent_param(struct uevent *event, char *param_name) -{ - int i; - - for (i = 0; i < UEVENT_PARAMS_MAX; i++) { - if (!event->param[i]) - break; - if (!strncmp(event->param[i], param_name, strlen(param_name))) - return &event->param[i][strlen(param_name) + 1]; - } - - LOGE("get_uevent_param(): No parameter '%s' found", param_name); - return NULL; -} - -/* - * --------------- - * Uevent Handlers - * --------------- - */ - -static int handle_powersupply_event(struct uevent *event) -{ - char *ps_type = get_uevent_param(event, "POWER_SUPPLY_TYPE"); - char *ps_cap = get_uevent_param(event, "POWER_SUPPLY_CAPACITY"); - - if (!strcasecmp(ps_type, "battery")) { - int capacity = atoi(ps_cap); - - if (capacity < 5) - low_batt = true; - else - low_batt = false; -LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open); - volmgr_safe_mode(low_batt || door_open); - } - return 0; -} - -static int handle_switch_event(struct uevent *event) -{ - char *name = get_uevent_param(event, "SWITCH_NAME"); - char *state = get_uevent_param(event, "SWITCH_STATE"); - - - if (!strcmp(name, "usb_mass_storage")) { - if (!strcmp(state, "online")) { - ums_hostconnected_set(true); - } else { - ums_hostconnected_set(false); - volmgr_enable_ums(false); - } - } else if (!strcmp(name, "sd-door")) { - if (!strcmp(state, "open")) - door_open = true; - else - door_open = false; -LOG_VOL("handle_powersupply_event(): low_batt = %d, door_open = %d", low_batt, door_open); - volmgr_safe_mode(low_batt || door_open); - } else - LOG_VOL("handle_switch_event(): Ignoring switch '%s'", name); - - return 0; -} - -static int handle_battery_event(struct uevent *event) -{ - return 0; -} - -static int handle_block_event(struct uevent *event) -{ - char mediapath[255]; - media_t *media; - int n; - int maj, min; - blkdev_t *blkdev; - - /* - * Look for backing media for this block device - */ - if (!strncmp(get_uevent_param(event, "DEVPATH"), - "/devices/virtual/", - strlen("/devices/virtual/"))) { - n = 0; - } else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "disk")) - n = 2; - else if (!strcmp(get_uevent_param(event, "DEVTYPE"), "partition")) - n = 3; - else { - LOGE("Bad blockdev type '%s'", get_uevent_param(event, "DEVTYPE")); - return -EINVAL; - } - - truncate_sysfs_path(event->path, n, mediapath); - - if (!(media = media_lookup_by_path(mediapath, false))) { -#if DEBUG_UEVENT - LOG_VOL("No backend media found @ device path '%s'", mediapath); -#endif - return 0; - } - - maj = atoi(get_uevent_param(event, "MAJOR")); - min = atoi(get_uevent_param(event, "MINOR")); - - if (event->action == action_add) { - blkdev_t *disk; - - /* - * If there isn't a disk already its because *we* - * are the disk - */ - disk = blkdev_lookup_by_devno(maj, 0); - - if (!(blkdev = blkdev_create(disk, - event->path, - maj, - min, - media, - get_uevent_param(event, "DEVTYPE")))) { - LOGE("Unable to allocate new blkdev (%m)"); - return -1; - } - - blkdev_refresh(blkdev); - - /* - * Add the blkdev to media - */ - int rc; - if ((rc = media_add_blkdev(media, blkdev)) < 0) { - LOGE("Unable to add blkdev to card (%d)", rc); - return rc; - } - - LOG_VOL("New blkdev %d.%d on media %s, media path %s, Dpp %d", - blkdev->major, blkdev->minor, media->name, mediapath, - blkdev_get_num_pending_partitions(blkdev->disk)); - - if (blkdev_get_num_pending_partitions(blkdev->disk) == 0) { - if ((rc = volmgr_consider_disk(blkdev->disk)) < 0) { - LOGE("Volmgr failed to handle device (%d)", rc); - return rc; - } - } - } else if (event->action == action_remove) { - if (!(blkdev = blkdev_lookup_by_devno(maj, min))) - return 0; - - LOG_VOL("Destroying blkdev %d.%d @ %s on media %s", blkdev->major, - blkdev->minor, blkdev->devpath, media->name); - volmgr_notify_eject(blkdev, _cb_blkdev_ok_to_destroy); - - } else if (event->action == action_change) { - if (!(blkdev = blkdev_lookup_by_devno(maj, min))) - return 0; - - LOG_VOL("Modified blkdev %d.%d @ %s on media %s", blkdev->major, - blkdev->minor, blkdev->devpath, media->name); - - blkdev_refresh(blkdev); - } else { -#if DEBUG_UEVENT - LOG_VOL("No handler implemented for action %d", event->action); -#endif - } - return 0; -} - -static void _cb_blkdev_ok_to_destroy(blkdev_t *dev) -{ - media_t *media = media_lookup_by_dev(dev); - if (media) - media_remove_blkdev(media, dev); - blkdev_destroy(dev); -} - -static int handle_bdi_event(struct uevent *event) -{ - return 0; -} - -static int handle_mmc_event(struct uevent *event) -{ - if (event->action == action_add) { - media_t *media; - char serial[80]; - char *type; - - /* - * Pull card information from sysfs - */ - type = get_uevent_param(event, "MMC_TYPE"); - if (strcmp(type, "SD") && strcmp(type, "MMC")) - return 0; - - read_sysfs_var(serial, sizeof(serial), event->path, "serial"); - if (!(media = media_create(event->path, - get_uevent_param(event, "MMC_NAME"), - serial, - media_mmc))) { - LOGE("Unable to allocate new media (%m)"); - return -1; - } - LOG_VOL("New MMC card '%s' (serial %u) added @ %s", media->name, - media->serial, media->devpath); - } else if (event->action == action_remove) { - media_t *media; - - if (!(media = media_lookup_by_path(event->path, false))) { - LOGE("Unable to lookup media '%s'", event->path); - return -1; - } - - LOG_VOL("MMC card '%s' (serial %u) @ %s removed", media->name, - media->serial, media->devpath); - media_destroy(media); - } else { -#if DEBUG_UEVENT - LOG_VOL("No handler implemented for action %d", event->action); -#endif - } - - return 0; -} diff --git a/vold/uevent.h b/vold/uevent.h deleted file mode 100644 index 0e9e6716c73948766d837e4bb5337f6d72dbff65..0000000000000000000000000000000000000000 --- a/vold/uevent.h +++ /dev/null @@ -1,21 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _UEVENT_MSG_H -#define _UEVENT_MSG_H - -#endif diff --git a/vold/ums.c b/vold/ums.c deleted file mode 100644 index 4d0fc2590c4e5765956ee53d45a72a5d037897ec..0000000000000000000000000000000000000000 --- a/vold/ums.c +++ /dev/null @@ -1,129 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fcntl.h> -#include <errno.h> - -#include "vold.h" -#include "ums.h" - -#define DEBUG_UMS 0 - -static boolean host_connected = false; -static boolean ums_enabled = false; - -int ums_bootstrap(void) -{ - return 0; -} - -void ums_enabled_set(boolean enabled) -{ - ums_enabled = enabled; - send_msg(enabled ? VOLD_EVT_UMS_ENABLED : VOLD_EVT_UMS_DISABLED); -} - -boolean ums_enabled_get() -{ - return ums_enabled; -} - -void ums_hostconnected_set(boolean connected) -{ -#if DEBUG_UMS - LOG_VOL("ums_hostconnected_set(%d):", connected); -#endif - host_connected = connected; - - if (!connected) - ums_enabled_set(false); - send_msg(connected ? VOLD_EVT_UMS_CONNECTED : VOLD_EVT_UMS_DISCONNECTED); -} - -int ums_enable(char *dev_fspath, char *lun_syspath) -{ - LOG_VOL("ums_enable(%s, %s):", dev_fspath, lun_syspath); - - int fd; - char filename[255]; - - sprintf(filename, "/sys/%s/file", lun_syspath); - if ((fd = open(filename, O_WRONLY)) < 0) { - LOGE("Unable to open '%s' (%s)", filename, strerror(errno)); - return -errno; - } - - if (write(fd, dev_fspath, strlen(dev_fspath)) < 0) { - LOGE("Unable to write to ums lunfile (%s)", strerror(errno)); - close(fd); - return -errno; - } - - close(fd); - return 0; -} - -int ums_disable(char *lun_syspath) -{ -#if DEBUG_UMS - LOG_VOL("ums_disable(%s):", lun_syspath); -#endif - - int fd; - char filename[255]; - - sprintf(filename, "/sys/%s/file", lun_syspath); - if ((fd = open(filename, O_WRONLY)) < 0) { - LOGE("Unable to open '%s' (%s)", filename, strerror(errno)); - return -errno; - } - - char ch = 0; - - if (write(fd, &ch, 1) < 0) { - LOGE("Unable to write to ums lunfile (%s)", strerror(errno)); - close(fd); - return -errno; - } - - close(fd); - return 0; -} - -boolean ums_hostconnected_get(void) -{ - return host_connected; -} - -int ums_send_status(void) -{ - int rc; - -#if DEBUG_UMS - LOG_VOL("ums_send_status():"); -#endif - - rc = send_msg(ums_enabled_get() ? VOLD_EVT_UMS_ENABLED : - VOLD_EVT_UMS_DISABLED); - if (rc < 0) - return rc; - - rc = send_msg(ums_hostconnected_get() ? VOLD_EVT_UMS_CONNECTED : - VOLD_EVT_UMS_DISCONNECTED); - - return rc; -} diff --git a/vold/ums.h b/vold/ums.h deleted file mode 100644 index 02cdec37c8a842b0d32242fe6c8c7ae5ba70b097..0000000000000000000000000000000000000000 --- a/vold/ums.h +++ /dev/null @@ -1,31 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _UMS_H -#define _UMS_H - -// these must match the corresponding strings in java/android/android/os/UsbListener.java -#define VOLD_EVT_UMS_ENABLED "ums_enabled" -#define VOLD_EVT_UMS_DISABLED "ums_disabled" -#define VOLD_EVT_UMS_CONNECTED "ums_connected" -#define VOLD_EVT_UMS_DISCONNECTED "ums_disconnected" - - -int ums_send_status(void); -int ums_enable(char *device_file, char *lun_syspath); -int ums_disable(char *lun_syspath); -#endif diff --git a/vold/vold.c b/vold/vold.c deleted file mode 100644 index 17331ac4e5d73bdf9a2010c3726efd4f0dd46d4b..0000000000000000000000000000000000000000 --- a/vold/vold.c +++ /dev/null @@ -1,234 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <string.h> -#include <fcntl.h> -#include <pthread.h> - -#include <sys/socket.h> -#include <sys/select.h> -#include <sys/time.h> -#include <sys/types.h> -#include <sys/un.h> - -#include <cutils/config_utils.h> -#include <cutils/cpu_info.h> -#include <cutils/properties.h> -#include <cutils/sockets.h> - -#include <linux/netlink.h> - -#include <private/android_filesystem_config.h> - -#include "vold.h" -#include "volmgr.h" - - -#define VOLD_SOCKET "vold" - -/* - * Globals - */ - -static int ver_major = 2; -static int ver_minor = 0; -static pthread_mutex_t write_mutex = PTHREAD_MUTEX_INITIALIZER; -static int fw_sock = -1; - -int main(int argc, char **argv) -{ - int door_sock = -1; - int uevent_sock = -1; - struct sockaddr_nl nladdr; - int uevent_sz = 64 * 1024; - - LOG_VOL("Android Volume Daemon version %d.%d", ver_major, ver_minor); - - /* - * Create all the various sockets we'll need - */ - - // Socket to listen on for incomming framework connections - if ((door_sock = android_get_control_socket(VOLD_SOCKET)) < 0) { - LOGE("Obtaining file descriptor socket '%s' failed: %s", - VOLD_SOCKET, strerror(errno)); - exit(1); - } - - if (listen(door_sock, 4) < 0) { - LOGE("Unable to listen on fd '%d' for socket '%s': %s", - door_sock, VOLD_SOCKET, strerror(errno)); - exit(1); - } - - mkdir("/dev/block/vold", 0755); - - // Socket to listen on for uevent changes - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = getpid(); - nladdr.nl_groups = 0xffffffff; - - if ((uevent_sock = socket(PF_NETLINK, - SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) { - LOGE("Unable to create uevent socket: %s", strerror(errno)); - exit(1); - } - - if (setsockopt(uevent_sock, SOL_SOCKET, SO_RCVBUFFORCE, &uevent_sz, - sizeof(uevent_sz)) < 0) { - LOGE("Unable to set uevent socket options: %s", strerror(errno)); - exit(1); - } - - if (bind(uevent_sock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) { - LOGE("Unable to bind uevent socket: %s", strerror(errno)); - exit(1); - } - - /* - * Bootstrap - */ - - // Volume Manager - volmgr_bootstrap(); - - // SD Card system - mmc_bootstrap(); - - // USB Mass Storage - ums_bootstrap(); - - // Switch - switch_bootstrap(); - - /* - * Main loop - */ - LOG_VOL("Bootstrapping complete"); - while(1) { - fd_set read_fds; - struct timeval to; - int max = 0; - int rc = 0; - - to.tv_sec = (60 * 60); - to.tv_usec = 0; - - FD_ZERO(&read_fds); - FD_SET(door_sock, &read_fds); - if (door_sock > max) - max = door_sock; - FD_SET(uevent_sock, &read_fds); - if (uevent_sock > max) - max = uevent_sock; - - if (fw_sock != -1) { - FD_SET(fw_sock, &read_fds); - if (fw_sock > max) - max = fw_sock; - } - - if ((rc = select(max + 1, &read_fds, NULL, NULL, &to)) < 0) { - LOGE("select() failed (%s)", strerror(errno)); - sleep(1); - continue; - } - - if (!rc) { - continue; - } - - if (FD_ISSET(door_sock, &read_fds)) { - struct sockaddr addr; - socklen_t alen; - - alen = sizeof(addr); - - if (fw_sock != -1) { - LOGE("Dropping duplicate framework connection"); - int tmp = accept(door_sock, &addr, &alen); - close(tmp); - continue; - } - - if ((fw_sock = accept(door_sock, &addr, &alen)) < 0) { - LOGE("Unable to accept framework connection (%s)", - strerror(errno)); - } - LOG_VOL("Accepted connection from framework"); - if ((rc = volmgr_send_states()) < 0) { - LOGE("Unable to send volmgr status to framework (%d)", rc); - } - } - - if (FD_ISSET(fw_sock, &read_fds)) { - if ((rc = process_framework_command(fw_sock)) < 0) { - if (rc == -ECONNRESET) { - LOGE("Framework disconnected"); - close(fw_sock); - fw_sock = -1; - } else { - LOGE("Error processing framework command (%s)", - strerror(errno)); - } - } - } - - if (FD_ISSET(uevent_sock, &read_fds)) { - if ((rc = process_uevent_message(uevent_sock)) < 0) { - LOGE("Error processing uevent msg (%s)", strerror(errno)); - } - } - } // while - -} - -int send_msg(char* message) -{ - int result = -1; - - pthread_mutex_lock(&write_mutex); - - LOG_VOL("send_msg(%s):", message); - - if (fw_sock >= 0) - result = write(fw_sock, message, strlen(message) + 1); - - pthread_mutex_unlock(&write_mutex); - - return result; -} - -int send_msg_with_data(char *message, char *data) -{ - int result = -1; - - char* buffer = (char *)alloca(strlen(message) + strlen(data) + 1); - if (!buffer) { - LOGE("alloca failed in send_msg_with_data"); - return -1; - } - - strcpy(buffer, message); - strcat(buffer, data); - return send_msg(buffer); -} diff --git a/vold/vold.h b/vold/vold.h deleted file mode 100644 index 0876bec9318f96f74a915a29b44030ee4c7b9798..0000000000000000000000000000000000000000 --- a/vold/vold.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VOLD_H__ -#define VOLD_H__ - -#define LOG_TAG "vold" -#include "cutils/log.h" - -typedef int boolean; -enum { - false = 0, - true = 1 -}; - -#define DEVPATH "/dev/block/" -#define DEVPATHLENGTH 11 - -#define WEXITSTATUS(status) (((status) & 0xff00) >> 8) - -// Set this for logging error messages -#define ENABLE_LOG_ERROR - -// set this to log vold events -#define ENABLE_LOG_VOL - -#ifdef ENABLE_LOG_ERROR -#define LOG_ERROR(fmt, args...) \ - { LOGE(fmt , ## args); } -#else -#define LOG_ERROR(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_ERROR */ - -#ifdef ENABLE_LOG_VOL -#define LOG_VOL(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_VOL(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_VOL */ - -#ifdef ENABLE_LOG_SERVER -#define LOG_SERVER(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_SERVER(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_SERVER */ - -#ifdef ENABLE_LOG_ASEC -#define LOG_ASEC(fmt, args...) \ - { LOGD(fmt , ## args); } -#else -#define LOG_ASEC(fmt, args...) \ - do { } while (0) -#endif /* ENABLE_LOG_ASEC */ - -/* - * Prototypes - */ - -int process_framework_command(int socket); - -int process_inotify_event(int fd); -int inotify_bootstrap(void); - -int process_uevent_message(int socket); -int simulate_uevent(char *subsystem, char *path, char *action, char **params); - -int mmc_bootstrap(void); -int ums_bootstrap(void); - -int volmgr_bootstrap(void); - -int switch_bootstrap(void); - -void *read_file(char *filename, ssize_t *_size); -char *truncate_sysfs_path(char *path, int num_elements_to_remove, char *buffer); -char *read_sysfs_var(char *buffer, size_t maxlen, char *devpath, char *var); - -void ums_hostconnected_set(boolean connected); -boolean ums_hostconnected_get(void); - -int send_msg(char *msg); -int send_msg_with_data(char *msg, char *data); -#endif diff --git a/vold/volmgr.c b/vold/volmgr.c deleted file mode 100644 index c3ce8d174010865e94e3e667f2c9cf48b7161989..0000000000000000000000000000000000000000 --- a/vold/volmgr.c +++ /dev/null @@ -1,1229 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <dirent.h> -#include <unistd.h> -#include <sched.h> - -#include <sys/mount.h> - -#include <cutils/config_utils.h> -#include <cutils/properties.h> - -#include "vold.h" -#include "volmgr.h" -#include "blkdev.h" -#include "ums.h" -#include "format.h" -#include "devmapper.h" - -#include "volmgr_ext3.h" -#include "volmgr_vfat.h" - -#define DEBUG_VOLMGR 0 - -static volume_t *vol_root = NULL; -static boolean safe_mode = true; - -static struct volmgr_fstable_entry fs_table[] = { - { "ext3", ext_identify, ext_check, ext_mount , true }, - { "vfat", vfat_identify, vfat_check, vfat_mount , false }, - { NULL, NULL, NULL, NULL , false} -}; - -struct _volume_state_event_map { - volume_state_t state; - char *event; - char *property_val; -}; - -static struct _volume_state_event_map volume_state_strings[] = { - { volstate_unknown, "volstate_unknown:", "unknown" }, - { volstate_nomedia, VOLD_EVT_NOMEDIA, VOLD_ES_PVAL_NOMEDIA }, - { volstate_unmounted, VOLD_EVT_UNMOUNTED, VOLD_ES_PVAL_UNMOUNTED }, - { volstate_checking, VOLD_EVT_CHECKING, VOLD_ES_PVAL_CHECKING }, - { volstate_mounted, VOLD_EVT_MOUNTED, VOLD_ES_PVAL_MOUNTED }, - { volstate_mounted_ro, VOLD_EVT_MOUNTED_RO, VOLD_ES_PVAL_MOUNTED_RO }, - { volstate_badremoval, VOLD_EVT_BADREMOVAL, VOLD_ES_PVAL_BADREMOVAL }, - { volstate_damaged, VOLD_EVT_DAMAGED, VOLD_ES_PVAL_DAMAGED }, - { volstate_nofs, VOLD_EVT_NOFS, VOLD_ES_PVAL_NOFS }, - { volstate_ums, VOLD_EVT_UMS, VOLD_ES_PVAL_UMS }, - { 0, NULL, NULL } -}; - - -static int volmgr_readconfig(char *cfg_path); -static int volmgr_config_volume(cnode *node); -static volume_t *volmgr_lookup_volume_by_mediapath(char *media_path, boolean fuzzy); -static volume_t *volmgr_lookup_volume_by_dev(blkdev_t *dev); -static int _volmgr_start(volume_t *vol, blkdev_t *dev); -static int volmgr_start_fs(struct volmgr_fstable_entry *fs, volume_t *vol, blkdev_t *dev); -static void *volmgr_start_fs_thread(void *arg); -static void volmgr_start_fs_thread_sighandler(int signo); -static void volume_setstate(volume_t *vol, volume_state_t state); -static char *conv_volstate_to_eventstr(volume_state_t state); -static char *conv_volstate_to_propstr(volume_state_t state); -static int volume_send_state(volume_t *vol); -static void _cb_volstopped_for_ums_enable(volume_t *v, void *arg); -static int _volmgr_enable_ums(volume_t *); -static int volmgr_shutdown_volume(volume_t *v, void (* cb) (volume_t *, void *arg), boolean emit_statechange); -static int volmgr_stop_volume(volume_t *v, void (*cb) (volume_t *, void *), void *arg, boolean emit_statechange); -static void _cb_volume_stopped_for_eject(volume_t *v, void *arg); -static void _cb_volume_stopped_for_shutdown(volume_t *v, void *arg); -static int _volmgr_consider_disk_and_vol(volume_t *vol, blkdev_t *dev); -static void volmgr_uncage_reaper(volume_t *vol, void (* cb) (volume_t *, void *arg), void *arg); -static void volmgr_reaper_thread_sighandler(int signo); -static void volmgr_add_mediapath_to_volume(volume_t *v, char *media_path); -static int volmgr_send_eject_request(volume_t *v); -static volume_t *volmgr_lookup_volume_by_mountpoint(char *mount_point, boolean leave_locked); - -static boolean _mountpoint_mounted(char *mp) -{ - char device[256]; - char mount_path[256]; - char rest[256]; - FILE *fp; - char line[1024]; - - if (!(fp = fopen("/proc/mounts", "r"))) { - LOGE("Error opening /proc/mounts (%s)", strerror(errno)); - return false; - } - - while(fgets(line, sizeof(line), fp)) { - line[strlen(line)-1] = '\0'; - sscanf(line, "%255s %255s %255s\n", device, mount_path, rest); - if (!strcmp(mount_path, mp)) { - fclose(fp); - return true; - } - - } - - fclose(fp); - return false; -} - -/* - * Public functions - */ - -int volmgr_set_volume_key(char *mount_point, unsigned char *key) -{ - volume_t *v = volmgr_lookup_volume_by_mountpoint(mount_point, true); - - if (!v) - return -ENOENT; - - if (v->media_type != media_devmapper) { - LOGE("Cannot set key on a non devmapper volume"); - pthread_mutex_unlock(&v->lock); - return -EINVAL; - } - - memcpy(v->dm->key, key, sizeof(v->dm->key)); - pthread_mutex_unlock(&v->lock); - return 0; -} - -int volmgr_format_volume(char *mount_point) -{ - int rc; - volume_t *v; - - LOG_VOL("volmgr_format_volume(%s):", mount_point); - - v = volmgr_lookup_volume_by_mountpoint(mount_point, true); - - if (!v) - return -ENOENT; - - if (v->state == volstate_mounted || - v->state == volstate_mounted_ro || - v->state == volstate_ums || - v->state == volstate_checking) { - LOGE("Can't format '%s', currently in state %d", mount_point, v->state); - pthread_mutex_unlock(&v->lock); - return -EBUSY; - } else if (v->state == volstate_nomedia && - v->media_type != media_devmapper) { - LOGE("Can't format '%s', (no media)", mount_point); - pthread_mutex_unlock(&v->lock); - return -ENOMEDIUM; - } - - // XXX:Reject if the underlying source media is not present - - if (v->media_type == media_devmapper) { - if ((rc = devmapper_genesis(v->dm)) < 0) { - LOGE("devmapper genesis failed for %s (%d)", mount_point, rc); - pthread_mutex_unlock(&v->lock); - return rc; - } - } else { - if ((rc = initialize_mbr(v->dev->disk)) < 0) { - LOGE("MBR init failed for %s (%d)", mount_point, rc); - pthread_mutex_unlock(&v->lock); - return rc; - } - } - - volume_setstate(v, volstate_formatting); - pthread_mutex_unlock(&v->lock); - return rc; -} - -int volmgr_bootstrap(void) -{ - int rc; - - if ((rc = volmgr_readconfig("/system/etc/vold.conf")) < 0) { - LOGE("Unable to process config"); - return rc; - } - - /* - * Check to see if any of our volumes is mounted - */ - volume_t *v = vol_root; - while (v) { - if (_mountpoint_mounted(v->mount_point)) { - LOG_VOL("Volume '%s' already mounted at startup", v->mount_point); - v->state = volstate_mounted; - } - v = v->next; - } - - return 0; -} - -int volmgr_safe_mode(boolean enable) -{ - if (enable == safe_mode) - return 0; - - safe_mode = enable; - - volume_t *v = vol_root; - int rc; - - while (v) { - pthread_mutex_lock(&v->lock); - if (v->state == volstate_mounted && v->fs) { - rc = v->fs->mount_fn(v->dev, v, safe_mode); - if (!rc) { - LOG_VOL("Safe mode %s on %s", (enable ? "enabled" : "disabled"), v->mount_point); - } else { - LOGE("Failed to %s safe-mode on %s (%s)", - (enable ? "enable" : "disable" ), v->mount_point, strerror(-rc)); - } - } - - pthread_mutex_unlock(&v->lock); - v = v->next; - } - - return 0; -} - -int volmgr_send_states(void) -{ - volume_t *vol_scan = vol_root; - int rc; - - while (vol_scan) { - pthread_mutex_lock(&vol_scan->lock); - if ((rc = volume_send_state(vol_scan)) < 0) { - LOGE("Error sending state to framework (%d)", rc); - } - pthread_mutex_unlock(&vol_scan->lock); - vol_scan = vol_scan->next; - break; // XXX: - } - - return 0; -} - -/* - * Called when a block device is ready to be - * evaluated by the volume manager. - */ -int volmgr_consider_disk(blkdev_t *dev) -{ - volume_t *vol; - - if (!(vol = volmgr_lookup_volume_by_mediapath(dev->media->devpath, true))) - return 0; - - pthread_mutex_lock(&vol->lock); - - if (vol->state == volstate_mounted) { - LOGE("Volume %s already mounted (did we just crash?)", vol->mount_point); - pthread_mutex_unlock(&vol->lock); - return 0; - } - - int rc = _volmgr_consider_disk_and_vol(vol, dev); - pthread_mutex_unlock(&vol->lock); - return rc; -} - -int volmgr_start_volume_by_mountpoint(char *mount_point) -{ - volume_t *v; - - v = volmgr_lookup_volume_by_mountpoint(mount_point, true); - if (!v) - return -ENOENT; - - if (v->media_type == media_devmapper) { - if (devmapper_start(v->dm) < 0) { - LOGE("volmgr failed to start devmapper volume '%s'", - v->mount_point); - } - } else if (v->media_type == media_mmc) { - if (!v->dev) { - LOGE("Cannot start volume '%s' (volume is not bound)", mount_point); - pthread_mutex_unlock(&v->lock); - return -ENOENT; - } - - if (_volmgr_consider_disk_and_vol(v, v->dev->disk) < 0) { - LOGE("volmgr failed to start volume '%s'", v->mount_point); - } - } - - pthread_mutex_unlock(&v->lock); - return 0; -} - -static void _cb_volstopped_for_devmapper_teardown(volume_t *v, void *arg) -{ - devmapper_stop(v->dm); - volume_setstate(v, volstate_nomedia); - pthread_mutex_unlock(&v->lock); -} - -int volmgr_stop_volume_by_mountpoint(char *mount_point) -{ - int rc; - volume_t *v; - - v = volmgr_lookup_volume_by_mountpoint(mount_point, true); - if (!v) - return -ENOENT; - - if (v->state == volstate_mounted) - volmgr_send_eject_request(v); - - if (v->media_type == media_devmapper) - rc = volmgr_shutdown_volume(v, _cb_volstopped_for_devmapper_teardown, false); - else - rc = volmgr_shutdown_volume(v, NULL, true); - - /* - * If shutdown returns -EINPROGRESS, - * do *not* release the lock as - * it is now owned by the reaper thread - */ - if (rc != -EINPROGRESS) { - if (rc) - LOGE("unable to shutdown volume '%s'", v->mount_point); - pthread_mutex_unlock(&v->lock); - } - return 0; -} - -int volmgr_notify_eject(blkdev_t *dev, void (* cb) (blkdev_t *)) -{ - LOG_VOL("Volmgr notified of %d:%d eject", dev->major, dev->minor); - - volume_t *v; - int rc; - - // XXX: Partitioning support is going to need us to stop *all* - // devices in this volume - if (!(v = volmgr_lookup_volume_by_dev(dev))) { - if (cb) - cb(dev); - return 0; - } - - pthread_mutex_lock(&v->lock); - - volume_state_t old_state = v->state; - - if (v->state == volstate_mounted || - v->state == volstate_ums || - v->state == volstate_checking) { - - volume_setstate(v, volstate_badremoval); - - /* - * Stop any devmapper volumes which - * are using us as a source - * XXX: We may need to enforce stricter - * order here - */ - volume_t *dmvol = vol_root; - while (dmvol) { - if ((dmvol->media_type == media_devmapper) && - (dmvol->dm->src_type == dmsrc_loopback) && - (!strncmp(dmvol->dm->type_data.loop.loop_src, - v->mount_point, strlen(v->mount_point)))) { - - pthread_mutex_lock(&dmvol->lock); - if (dmvol->state != volstate_nomedia) { - rc = volmgr_shutdown_volume(dmvol, _cb_volstopped_for_devmapper_teardown, false); - if (rc != -EINPROGRESS) { - if (rc) - LOGE("unable to shutdown volume '%s'", v->mount_point); - pthread_mutex_unlock(&dmvol->lock); - } - } else - pthread_mutex_unlock(&dmvol->lock); - } - dmvol = dmvol->next; - } - - } else if (v->state == volstate_formatting) { - /* - * The device is being ejected due to - * kernel disk revalidation. - */ - LOG_VOL("Volmgr ignoring eject of %d:%d (volume formatting)", - dev->major, dev->minor); - if (cb) - cb(dev); - pthread_mutex_unlock(&v->lock); - return 0; - } else - volume_setstate(v, volstate_nomedia); - - if (old_state == volstate_ums) { - ums_disable(v->ums_path); - pthread_mutex_unlock(&v->lock); - } else { - int rc = volmgr_stop_volume(v, _cb_volume_stopped_for_eject, cb, false); - if (rc != -EINPROGRESS) { - if (rc) - LOGE("unable to shutdown volume '%s'", v->mount_point); - pthread_mutex_unlock(&v->lock); - } - } - return 0; -} - -static void _cb_volume_stopped_for_eject(volume_t *v, void *arg) -{ - void (* eject_cb) (blkdev_t *) = arg; - -#if DEBUG_VOLMGR - LOG_VOL("Volume %s has been stopped for eject", v->mount_point); -#endif - - if (eject_cb) - eject_cb(v->dev); - v->dev = NULL; // Clear dev because its being ejected -} - -/* - * Instructs the volume manager to enable or disable USB mass storage - * on any volumes configured to use it. - */ -int volmgr_enable_ums(boolean enable) -{ - volume_t *v = vol_root; - - while(v) { - if (v->ums_path) { - int rc; - - if (enable) { - pthread_mutex_lock(&v->lock); - if (v->state == volstate_mounted) - volmgr_send_eject_request(v); - else if (v->state == volstate_ums) { - pthread_mutex_unlock(&v->lock); - goto next_vol; - } - - // Stop the volume, and enable UMS in the callback - rc = volmgr_shutdown_volume(v, _cb_volstopped_for_ums_enable, false); - if (rc != -EINPROGRESS) { - if (rc) - LOGE("unable to shutdown volume '%s'", v->mount_point); - pthread_mutex_unlock(&v->lock); - } - } else { - // Disable UMS - pthread_mutex_lock(&v->lock); - if (v->state != volstate_ums) { - pthread_mutex_unlock(&v->lock); - goto next_vol; - } - - if ((rc = ums_disable(v->ums_path)) < 0) { - LOGE("unable to disable ums on '%s'", v->mount_point); - pthread_mutex_unlock(&v->lock); - continue; - } - - LOG_VOL("Kick-starting volume %d:%d after UMS disable", - v->dev->disk->major, v->dev->disk->minor); - // Start volume - if ((rc = _volmgr_consider_disk_and_vol(v, v->dev->disk)) < 0) { - LOGE("volmgr failed to consider disk %d:%d", - v->dev->disk->major, v->dev->disk->minor); - } - pthread_mutex_unlock(&v->lock); - } - } - next_vol: - v = v->next; - } - return 0; -} - -/* - * Static functions - */ - -static int volmgr_send_eject_request(volume_t *v) -{ - return send_msg_with_data(VOLD_EVT_EJECTING, v->mount_point); -} - -// vol->lock must be held! -static int _volmgr_consider_disk_and_vol(volume_t *vol, blkdev_t *dev) -{ - int rc = 0; - -#if DEBUG_VOLMGR - LOG_VOL("volmgr_consider_disk_and_vol(%s, %d:%d):", vol->mount_point, - dev->major, dev->minor); -#endif - - if (vol->state == volstate_unknown || - vol->state == volstate_mounted || - vol->state == volstate_mounted_ro || - vol->state == volstate_damaged) { - LOGE("Cannot consider volume '%s' because it is in state '%d", - vol->mount_point, vol->state); - return -EADDRINUSE; - } - - if (vol->state == volstate_formatting) { - LOG_VOL("Evaluating dev '%s' for formattable filesystems for '%s'", - dev->devpath, vol->mount_point); - /* - * Since we only support creating 1 partition (right now), - * we can just lookup the target by devno - */ - blkdev_t *part = blkdev_lookup_by_devno(dev->major, 1); - if (!part) { - part = blkdev_lookup_by_devno(dev->major, 0); - if (!part) { - LOGE("Unable to find device to format"); - return -ENODEV; - } - } - - if ((rc = format_partition(part, - vol->media_type == media_devmapper ? - FORMAT_TYPE_EXT2 : FORMAT_TYPE_FAT32)) < 0) { - LOGE("format failed (%d)", rc); - return rc; - } - - } - - LOG_VOL("Evaluating dev '%s' for mountable filesystems for '%s'", - dev->devpath, vol->mount_point); - - if (dev->nr_parts == 0) { - rc = _volmgr_start(vol, dev); -#if DEBUG_VOLMGR - LOG_VOL("_volmgr_start(%s, %d:%d) rc = %d", vol->mount_point, - dev->major, dev->minor, rc); -#endif - } else { - /* - * Device has multiple partitions - * This is where interesting partition policies could be implemented. - * For now just try them in sequence until one succeeds - */ - - rc = -ENODEV; - int i; - for (i = 0; i < dev->nr_parts; i++) { - blkdev_t *part = blkdev_lookup_by_devno(dev->major, (i+1)); - if (!part) { - LOGE("Error - unable to lookup partition for blkdev %d:%d", dev->major, (i+1)); - continue; - } - rc = _volmgr_start(vol, part); -#if DEBUG_VOLMGR - LOG_VOL("_volmgr_start(%s, %d:%d) rc = %d", - vol->mount_point, part->major, part->minor, rc); -#endif - if (!rc) - break; - } - - if (rc == -ENODEV) { - // Assert to make sure each partition had a backing blkdev - LOGE("Internal consistency error"); - return 0; - } - } - - if (rc == -ENODATA) { - LOGE("Device %d:%d contains no usable filesystems", - dev->major, dev->minor); - rc = 0; - } - - return rc; -} - -static void volmgr_reaper_thread_sighandler(int signo) -{ - LOGE("Volume reaper thread got signal %d", signo); -} - -static void __reaper_cleanup(void *arg) -{ - volume_t *vol = (volume_t *) arg; - - if (vol->worker_args.reaper_args.cb) - vol->worker_args.reaper_args.cb(vol, vol->worker_args.reaper_args.cb_arg); - - vol->worker_running = false; - - // Wake up anyone that was waiting on this thread - pthread_mutex_unlock(&vol->worker_sem); - - // Unlock the volume - pthread_mutex_unlock(&vol->lock); -} - -static void *volmgr_reaper_thread(void *arg) -{ - volume_t *vol = (volume_t *) arg; - - pthread_cleanup_push(__reaper_cleanup, arg); - - vol->worker_running = true; - vol->worker_pid = getpid(); - - struct sigaction actions; - - memset(&actions, 0, sizeof(actions)); - sigemptyset(&actions.sa_mask); - actions.sa_flags = 0; - actions.sa_handler = volmgr_reaper_thread_sighandler; - sigaction(SIGUSR1, &actions, NULL); - - LOG_VOL("Reaper here - working on %s", vol->mount_point); - - boolean send_sig_kill = false; - int i, rc; - - for (i = 0; i < 10; i++) { - errno = 0; - rc = umount(vol->mount_point); - LOG_VOL("volmngr reaper umount(%s) attempt %d (%s)", - vol->mount_point, i + 1, strerror(errno)); - if (!rc) - break; - if (rc && (errno == EINVAL || errno == ENOENT)) { - rc = 0; - break; - } - sleep(1); - if (i >= 4) { - KillProcessesWithOpenFiles(vol->mount_point, send_sig_kill, NULL, 0); - if (!send_sig_kill) - send_sig_kill = true; - } - } - - if (!rc) { - LOG_VOL("Reaper sucessfully unmounted %s", vol->mount_point); - vol->fs = NULL; - volume_setstate(vol, volstate_unmounted); - } else { - LOGE("Unable to unmount!! (%d)", rc); - } - - out: - pthread_cleanup_pop(1); - pthread_exit(NULL); - return NULL; -} - -// vol->lock must be held! -static void volmgr_uncage_reaper(volume_t *vol, void (* cb) (volume_t *, void *arg), void *arg) -{ - - if (vol->worker_running) { - LOGE("Worker thread is currently running.. waiting.."); - pthread_mutex_lock(&vol->worker_sem); - LOG_VOL("Worker thread now available"); - } - - vol->worker_args.reaper_args.cb = cb; - vol->worker_args.reaper_args.cb_arg = arg; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - pthread_create(&vol->worker_thread, &attr, volmgr_reaper_thread, vol); -} - -static int volmgr_stop_volume(volume_t *v, void (*cb) (volume_t *, void *), void *arg, boolean emit_statechange) -{ - int i, rc; - - if (v->state == volstate_mounted || v->state == volstate_badremoval) { - // Try to unmount right away (5 retries) - for (i = 0; i < 5; i++) { - rc = umount(v->mount_point); - if (!rc) - break; - - if (rc && (errno == EINVAL || errno == ENOENT)) { - rc = 0; - break; - } - - LOG_VOL("volmngr quick stop umount(%s) attempt %d (%s)", - v->mount_point, i + 1, strerror(errno)); - - if (i == 0) - usleep(1000 * 250); // First failure, sleep for 250 ms - else - sched_yield(); - } - - if (!rc) { - LOG_VOL("volmgr_stop_volume(%s): Volume unmounted sucessfully", - v->mount_point); - if (emit_statechange) - volume_setstate(v, volstate_unmounted); - v->fs = NULL; - goto out_cb_immed; - } - - /* - * Since the volume is still in use, dispatch the stopping to - * a thread - */ - LOG_VOL("Volume %s is busy (%d) - uncaging the reaper", v->mount_point, rc); - volmgr_uncage_reaper(v, cb, arg); - return -EINPROGRESS; - } else if (v->state == volstate_checking) { - volume_setstate(v, volstate_unmounted); - if (v->worker_running) { - LOG_VOL("Cancelling worker thread"); - pthread_kill(v->worker_thread, SIGUSR1); - } else - LOGE("Strange... we were in checking state but worker thread wasn't running.."); - goto out_cb_immed; - } - - out_cb_immed: - if (cb) - cb(v, arg); - return 0; -} - - -/* - * Gracefully stop a volume - * v->lock must be held! - * if we return -EINPROGRESS, do NOT release the lock as the reaper - * is using the volume - */ -static int volmgr_shutdown_volume(volume_t *v, void (* cb) (volume_t *, void *), boolean emit_statechange) -{ - return volmgr_stop_volume(v, cb, NULL, emit_statechange); -} - -static void _cb_volume_stopped_for_shutdown(volume_t *v, void *arg) -{ - void (* shutdown_cb) (volume_t *) = arg; - -#if DEBUG_VOLMGR - LOG_VOL("Volume %s has been stopped for shutdown", v->mount_point); -#endif - shutdown_cb(v); -} - - -/* - * Called when a volume is sucessfully unmounted for UMS enable - */ -static void _cb_volstopped_for_ums_enable(volume_t *v, void *arg) -{ - int rc; - char *devdir_path; - -#if DEBUG_VOLMGR - LOG_VOL("_cb_volstopped_for_ums_enable(%s):", v->mount_point); -#endif - devdir_path = blkdev_get_devpath(v->dev->disk); - - if ((rc = ums_enable(devdir_path, v->ums_path)) < 0) { - free(devdir_path); - LOGE("Error enabling ums (%d)", rc); - return; - } - free(devdir_path); - volume_setstate(v, volstate_ums); - pthread_mutex_unlock(&v->lock); -} - -static int volmgr_readconfig(char *cfg_path) -{ - cnode *root = config_node("", ""); - cnode *node; - - config_load_file(root, cfg_path); - node = root->first_child; - - while (node) { - if (!strncmp(node->name, "volume_", 7)) - volmgr_config_volume(node); - else - LOGE("Skipping unknown configuration node '%s'", node->name); - node = node->next; - } - return 0; -} - -static void volmgr_add_mediapath_to_volume(volume_t *v, char *media_path) -{ - int i; - -#if DEBUG_VOLMGR - LOG_VOL("volmgr_add_mediapath_to_volume(%p, %s):", v, media_path); -#endif - for (i = 0; i < VOLMGR_MAX_MEDIAPATHS_PER_VOLUME; i++) { - if (!v->media_paths[i]) { - v->media_paths[i] = strdup(media_path); - return; - } - } - LOGE("Unable to add media path '%s' to volume (out of media slots)", media_path); -} - -static int volmgr_config_volume(cnode *node) -{ - volume_t *new; - int rc = 0, i; - - char *dm_src, *dm_src_type, *dm_tgt, *dm_param, *dm_tgtfs; - uint32_t dm_size_mb = 0; - - dm_src = dm_src_type = dm_tgt = dm_param = dm_tgtfs = NULL; -#if DEBUG_VOLMGR - LOG_VOL("volmgr_configure_volume(%s):", node->name); -#endif - if (!(new = malloc(sizeof(volume_t)))) - return -ENOMEM; - memset(new, 0, sizeof(volume_t)); - - new->state = volstate_nomedia; - pthread_mutex_init(&new->lock, NULL); - pthread_mutex_init(&new->worker_sem, NULL); - - cnode *child = node->first_child; - - while (child) { - if (!strcmp(child->name, "media_path")) - volmgr_add_mediapath_to_volume(new, child->value); - else if (!strcmp(child->name, "emu_media_path")) - volmgr_add_mediapath_to_volume(new, child->value); - else if (!strcmp(child->name, "media_type")) { - if (!strcmp(child->value, "mmc")) - new->media_type = media_mmc; - else if (!strcmp(child->value, "devmapper")) - new->media_type = media_devmapper; - else { - LOGE("Invalid media type '%s'", child->value); - rc = -EINVAL; - goto out_free; - } - } else if (!strcmp(child->name, "mount_point")) - new->mount_point = strdup(child->value); - else if (!strcmp(child->name, "ums_path")) - new->ums_path = strdup(child->value); - else if (!strcmp(child->name, "dm_src")) - dm_src = strdup(child->value); - else if (!strcmp(child->name, "dm_src_type")) - dm_src_type = strdup(child->value); - else if (!strcmp(child->name, "dm_src_size_mb")) - dm_size_mb = atoi(child->value); - else if (!strcmp(child->name, "dm_target")) - dm_tgt = strdup(child->value); - else if (!strcmp(child->name, "dm_target_params")) - dm_param = strdup(child->value); - else if (!strcmp(child->name, "dm_target_fs")) - dm_tgtfs = strdup(child->value); - else - LOGE("Ignoring unknown config entry '%s'", child->name); - child = child->next; - } - - if (new->media_type == media_mmc) { - if (!new->media_paths[0] || !new->mount_point || new->media_type == media_unknown) { - LOGE("Required configuration parameter missing for mmc volume"); - rc = -EINVAL; - goto out_free; - } - } else if (new->media_type == media_devmapper) { - if (!dm_src || !dm_src_type || !dm_tgt || - !dm_param || !dm_tgtfs || !dm_size_mb) { - LOGE("Required configuration parameter missing for devmapper volume"); - rc = -EINVAL; - goto out_free; - } - - char dm_mediapath[255]; - if (!(new->dm = devmapper_init(dm_src, dm_src_type, dm_size_mb, - dm_tgt, dm_param, dm_tgtfs, dm_mediapath))) { - LOGE("Unable to initialize devmapping"); - goto out_free; - } - LOG_VOL("media path for devmapper volume = '%s'", dm_mediapath); - volmgr_add_mediapath_to_volume(new, dm_mediapath); - } - - if (!vol_root) - vol_root = new; - else { - volume_t *scan = vol_root; - while (scan->next) - scan = scan->next; - scan->next = new; - } - - if (dm_src) - free(dm_src); - if (dm_src_type) - free(dm_src_type); - if (dm_tgt) - free(dm_tgt); - if (dm_param) - free(dm_param); - if (dm_tgtfs) - free(dm_tgtfs); - - return rc; - - out_free: - - if (dm_src) - free(dm_src); - if (dm_src_type) - free(dm_src_type); - if (dm_tgt) - free(dm_tgt); - if (dm_param) - free(dm_param); - if (dm_tgtfs) - free(dm_tgtfs); - - - for (i = 0; i < VOLMGR_MAX_MEDIAPATHS_PER_VOLUME; i++) { - if (new->media_paths[i]) - free(new->media_paths[i]); - } - if (new->mount_point) - free(new->mount_point); - if (new->ums_path) - free(new->ums_path); - return rc; -} - -static volume_t *volmgr_lookup_volume_by_dev(blkdev_t *dev) -{ - volume_t *scan = vol_root; - while(scan) { - if (scan->dev == dev) - return scan; - scan = scan->next; - } - return NULL; -} - -static volume_t *volmgr_lookup_volume_by_mountpoint(char *mount_point, boolean leave_locked) -{ - volume_t *v = vol_root; - - while(v) { - pthread_mutex_lock(&v->lock); - if (!strcmp(v->mount_point, mount_point)) { - if (!leave_locked) - pthread_mutex_unlock(&v->lock); - return v; - } - pthread_mutex_unlock(&v->lock); - v = v->next; - } - return NULL; -} - -static volume_t *volmgr_lookup_volume_by_mediapath(char *media_path, boolean fuzzy) -{ - volume_t *scan = vol_root; - int i; - - while (scan) { - - for (i = 0; i < VOLMGR_MAX_MEDIAPATHS_PER_VOLUME; i++) { - if (!scan->media_paths[i]) - continue; - - if (fuzzy && !strncmp(media_path, scan->media_paths[i], strlen(scan->media_paths[i]))) - return scan; - else if (!fuzzy && !strcmp(media_path, scan->media_paths[i])) - return scan; - } - - scan = scan->next; - } - return NULL; -} - -/* - * Attempt to bring a volume online - * Returns: 0 on success, errno on failure, with the following exceptions: - * - ENODATA - Unsupported filesystem type / blank - * vol->lock MUST be held! - */ -static int _volmgr_start(volume_t *vol, blkdev_t *dev) -{ - struct volmgr_fstable_entry *fs; - int rc = ENODATA; - -#if DEBUG_VOLMGR - LOG_VOL("_volmgr_start(%s, %d:%d):", vol->mount_point, - dev->major, dev->minor); -#endif - - if (vol->state == volstate_mounted) { - LOGE("Unable to start volume '%s' (already mounted)", vol->mount_point); - return -EBUSY; - } - - for (fs = fs_table; fs->name; fs++) { - if (!fs->identify_fn(dev)) - break; - } - - if (!fs) { - LOGE("No supported filesystems on %d:%d", dev->major, dev->minor); - volume_setstate(vol, volstate_nofs); - return -ENODATA; - } - - return volmgr_start_fs(fs, vol, dev); -} - -// vol->lock MUST be held! -static int volmgr_start_fs(struct volmgr_fstable_entry *fs, volume_t *vol, blkdev_t *dev) -{ - /* - * Spawn a thread to do the actual checking / mounting in - */ - - if (vol->worker_running) { - LOGE("Worker thread is currently running.. waiting.."); - pthread_mutex_lock(&vol->worker_sem); - LOG_VOL("Worker thread now available"); - } - - vol->dev = dev; - - vol->worker_args.start_args.fs = fs; - vol->worker_args.start_args.dev = dev; - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - - pthread_create(&vol->worker_thread, &attr, volmgr_start_fs_thread, vol); - - return 0; -} - -static void __start_fs_thread_lock_cleanup(void *arg) -{ - volume_t *vol = (volume_t *) arg; - -#if DEBUG_VOLMGR - LOG_VOL("__start_fs_thread_lock_cleanup(%s):", vol->mount_point); -#endif - - vol->worker_running = false; - - // Wake up anyone that was waiting on this thread - pthread_mutex_unlock(&vol->worker_sem); - - // Unlock the volume - pthread_mutex_unlock(&vol->lock); -} - -static void *volmgr_start_fs_thread(void *arg) -{ - volume_t *vol = (volume_t *) arg; - - pthread_cleanup_push(__start_fs_thread_lock_cleanup, arg); - pthread_mutex_lock(&vol->lock); - - vol->worker_running = true; - vol->worker_pid = getpid(); - - struct sigaction actions; - - memset(&actions, 0, sizeof(actions)); - sigemptyset(&actions.sa_mask); - actions.sa_flags = 0; - actions.sa_handler = volmgr_start_fs_thread_sighandler; - sigaction(SIGUSR1, &actions, NULL); - - struct volmgr_fstable_entry *fs = vol->worker_args.start_args.fs; - blkdev_t *dev = vol->worker_args.start_args.dev; - int rc; - -#if DEBUG_VOLMGR - LOG_VOL("Worker thread pid %d starting %s fs %d:%d on %s", getpid(), - fs->name, dev->major, dev->minor, vol->mount_point); -#endif - - if (fs->check_fn) { -#if DEBUG_VOLMGR - LOG_VOL("Starting %s filesystem check on %d:%d", fs->name, - dev->major, dev->minor); -#endif - volume_setstate(vol, volstate_checking); - pthread_mutex_unlock(&vol->lock); - rc = fs->check_fn(dev); - pthread_mutex_lock(&vol->lock); - if (vol->state != volstate_checking) { - LOG_VOL("filesystem check aborted"); - goto out; - } - - if (rc < 0) { - LOGE("%s filesystem check failed on %d:%d (%s)", fs->name, - dev->major, dev->minor, strerror(-rc)); - if (rc == -ENODATA) { - volume_setstate(vol, volstate_nofs); - goto out; - } - goto out_unmountable; - } -#if DEBUG_VOLMGR - LOG_VOL("%s filesystem check of %d:%d OK", fs->name, - dev->major, dev->minor); -#endif - } - - rc = fs->mount_fn(dev, vol, safe_mode); - if (!rc) { - LOG_VOL("Sucessfully mounted %s filesystem %d:%d on %s (safe-mode %s)", - fs->name, dev->major, dev->minor, vol->mount_point, - (safe_mode ? "on" : "off")); - vol->fs = fs; - volume_setstate(vol, volstate_mounted); - goto out; - } - - LOGE("%s filesystem mount of %d:%d failed (%d)", fs->name, dev->major, - dev->minor, rc); - - out_unmountable: - volume_setstate(vol, volstate_damaged); - out: - pthread_cleanup_pop(1); - pthread_exit(NULL); - return NULL; -} - -static void volmgr_start_fs_thread_sighandler(int signo) -{ - LOGE("Volume startup thread got signal %d", signo); -} - -static void volume_setstate(volume_t *vol, volume_state_t state) -{ - if (state == vol->state) - return; - -#if DEBUG_VOLMGR - LOG_VOL("Volume %s state change from %d -> %d", vol->mount_point, vol->state, state); -#endif - - vol->state = state; - - char *prop_val = conv_volstate_to_propstr(vol->state); - - if (prop_val) { - property_set(PROP_EXTERNAL_STORAGE_STATE, prop_val); - volume_send_state(vol); - } -} - -static int volume_send_state(volume_t *vol) -{ - char *event = conv_volstate_to_eventstr(vol->state); - - return send_msg_with_data(event, vol->mount_point); -} - -static char *conv_volstate_to_eventstr(volume_state_t state) -{ - int i; - - for (i = 0; volume_state_strings[i].event != NULL; i++) { - if (volume_state_strings[i].state == state) - break; - } - - return volume_state_strings[i].event; -} - -static char *conv_volstate_to_propstr(volume_state_t state) -{ - int i; - - for (i = 0; volume_state_strings[i].event != NULL; i++) { - if (volume_state_strings[i].state == state) - break; - } - - return volume_state_strings[i].property_val; -} - diff --git a/vold/volmgr.h b/vold/volmgr.h deleted file mode 100644 index 2c7ec503bbcce8ca1595891df387416563329bd7..0000000000000000000000000000000000000000 --- a/vold/volmgr.h +++ /dev/null @@ -1,135 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _VOLMGR_H -#define _VOLMGR_H - -#include <pthread.h> - -#include "vold.h" -#include "blkdev.h" -#include "media.h" -#include "devmapper.h" - -#define PROP_EXTERNAL_STORAGE_STATE "EXTERNAL_STORAGE_STATE" - -// these must match the corresponding states in the MediaState enum. -// A path to the volume mount point follows the colon -typedef enum volume_state { - volstate_unknown, - - volstate_nomedia, -#define VOLD_EVT_NOMEDIA "volume_nomedia:" -#define VOLD_ES_PVAL_NOMEDIA "removed" - - volstate_unmounted, -#define VOLD_EVT_UNMOUNTED "volume_unmounted:" -#define VOLD_ES_PVAL_UNMOUNTED "unmounted" - - volstate_checking, -#define VOLD_EVT_CHECKING "volume_checking:" -#define VOLD_ES_PVAL_CHECKING "checking" - - volstate_mounted, -#define VOLD_EVT_MOUNTED "volume_mounted:" -#define VOLD_ES_PVAL_MOUNTED "mounted" - - volstate_mounted_ro, -#define VOLD_EVT_MOUNTED_RO "volume_mounted_ro:" -#define VOLD_ES_PVAL_MOUNTED_RO "mounted_ro" - - volstate_badremoval, -#define VOLD_EVT_BADREMOVAL "volume_badremoval:" -#define VOLD_ES_PVAL_BADREMOVAL "bad_removal" - - volstate_damaged, -#define VOLD_EVT_DAMAGED "volume_damaged:" -#define VOLD_ES_PVAL_DAMAGED "unmountable" - - volstate_nofs, -#define VOLD_EVT_NOFS "volume_nofs:" -#define VOLD_ES_PVAL_NOFS "nofs" - - volstate_ums, -#define VOLD_EVT_UMS "volume_ums:" -#define VOLD_ES_PVAL_UMS "shared" - - volstate_ejecting, -#define VOLD_EVT_EJECTING "volume_ejecting:" -#define VOLD_ES_PVAL_EJECTING "ejecting" - - volstate_formatting, -} volume_state_t; - -struct volume; - -struct volmgr_fstable_entry { - char *name; - int (*identify_fn) (blkdev_t *dev); - int (*check_fn) (blkdev_t *dev); - int (*mount_fn) (blkdev_t *dev, struct volume *vol, boolean safe_mode); - boolean case_sensitive_paths; -}; - -struct volmgr_start_args { - struct volmgr_fstable_entry *fs; - blkdev_t *dev; -}; - -struct volmgr_reaper_args { - void (*cb) (struct volume *, void *); - void *cb_arg; -}; - -#define VOLMGR_MAX_MEDIAPATHS_PER_VOLUME 8 - -typedef struct volume { - char *media_paths[VOLMGR_MAX_MEDIAPATHS_PER_VOLUME]; - - media_type_t media_type; - char *mount_point; - char *ums_path; - struct devmapping *dm; - - pthread_mutex_t lock; - volume_state_t state; - blkdev_t *dev; - pid_t worker_pid; - pthread_t worker_thread; - union { - struct volmgr_start_args start_args; - struct volmgr_reaper_args reaper_args; - } worker_args; - boolean worker_running; - pthread_mutex_t worker_sem; - - struct volmgr_fstable_entry *fs; - - struct volume *next; -} volume_t; - -int volmgr_consider_disk(blkdev_t *dev); -int volmgr_notify_eject(blkdev_t *dev, void (* cb) (blkdev_t *)); -int volmgr_send_states(void); -int volmgr_enable_ums(boolean enable); -int volmgr_stop_volume_by_mountpoint(char *mount_point); -int volmgr_start_volume_by_mountpoint(char *mount_point); -int volmgr_safe_mode(boolean enable); -int volmgr_format_volume(char *mount_point); -int volmgr_set_volume_key(char *mount_point, unsigned char *key); -void KillProcessesWithOpenFiles(const char* mountPoint, boolean sigkill, int *excluded, int num_excluded); -#endif diff --git a/vold/volmgr_ext3.c b/vold/volmgr_ext3.c deleted file mode 100644 index 680be21900192f2cc90e8a72fd2fe77f11286112..0000000000000000000000000000000000000000 --- a/vold/volmgr_ext3.c +++ /dev/null @@ -1,184 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <fcntl.h> -#include <errno.h> - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mount.h> - -#include <linux/ext2_fs.h> -#include <linux/ext3_fs.h> - -#include "vold.h" -#include "volmgr.h" -#include "volmgr_ext3.h" -#include "logwrapper.h" - - -#define EXT_DEBUG 0 - -static char E2FSCK_PATH[] = "/system/bin/e2fsck"; - -int ext_identify(blkdev_t *dev) -{ - int rc = -1; - int fd; - struct ext3_super_block sb; - char *devpath; - -#if EXT_DEBUG - LOG_VOL("ext_identify(%d:%d):", dev-major, dev->minor); -#endif - - devpath = blkdev_get_devpath(dev); - - if ((fd = open(devpath, O_RDWR)) < 0) { - LOGE("Unable to open device '%s' (%s)", devpath, - strerror(errno)); - free(devpath); - return -errno; - } - - if (lseek(fd, 1024, SEEK_SET) < 0) { - LOGE("Unable to lseek to get superblock (%s)", strerror(errno)); - rc = -errno; - goto out; - } - - if (read(fd, &sb, sizeof(sb)) != sizeof(sb)) { - LOGE("Unable to read superblock (%s)", strerror(errno)); - rc = -errno; - goto out; - } - - if (sb.s_magic == EXT2_SUPER_MAGIC || - sb.s_magic == EXT3_SUPER_MAGIC) - rc = 0; - else - rc = -ENODATA; - - out: -#if EXT_DEBUG - LOG_VOL("ext_identify(%s): rc = %d", devpath, rc); -#endif - free(devpath); - close(fd); - return rc; -} - -int ext_check(blkdev_t *dev) -{ - char *devpath; - -#if EXT_DEBUG - LOG_VOL("ext_check(%s):", dev->dev_fspath); -#endif - - devpath = blkdev_get_devpath(dev); - - if (access(E2FSCK_PATH, X_OK)) { - LOGE("ext_check(%s): %s not found (skipping checks)", - devpath, E2FSCK_PATH); - free(devpath); - return 0; - } - - char *args[5]; - - args[0] = E2FSCK_PATH; - args[1] = "-v"; - args[2] = "-p"; - args[3] = devpath; - args[4] = NULL; - - int rc = logwrap(4, args); - - if (rc == 0) { - LOG_VOL("filesystem '%s' had no errors", devpath); - } else if (rc == 1) { - LOG_VOL("filesystem '%s' had corrected errors", devpath); - rc = 0; - } else if (rc == 2) { - LOGE("VOL volume '%s' had corrected errors (system should be rebooted)", devpath); - rc = -EIO; - } else if (rc == 4) { - LOGE("VOL volume '%s' had uncorrectable errors", devpath); - rc = -EIO; - } else if (rc == 8) { - LOGE("Operational error while checking volume '%s'", devpath); - rc = -EIO; - } else { - LOGE("Unknown e2fsck exit code (%d)", rc); - rc = -EIO; - } - free(devpath); - return rc; -} - -int ext_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode) -{ -#if EXT_DEBUG - LOG_VOL("ext_mount(%s, %s, %d):", dev->dev_fspath, vol->mount_point, safe_mode); -#endif - - char *fs[] = { "ext3", "ext2", NULL }; - char *devpath; - - devpath = blkdev_get_devpath(dev); - - int flags, rc = 0; - - flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_NOATIME | MS_NODIRATIME; - - if (safe_mode) - flags |= MS_SYNCHRONOUS; - - if (vol->state == volstate_mounted) { - LOG_VOL("Remounting %s on %s, safe mode %d", devpath, - vol->mount_point, safe_mode); - flags |= MS_REMOUNT; - } - - char **f; - for (f = fs; *f != NULL; f++) { - rc = mount(devpath, vol->mount_point, *f, flags, NULL); - if (rc && errno == EROFS) { - LOGE("ext_mount(%s, %s): Read only filesystem - retrying mount RO", - devpath, vol->mount_point); - flags |= MS_RDONLY; - rc = mount(devpath, vol->mount_point, *f, flags, NULL); - } -#if EXT_DEBUG - LOG_VOL("ext_mount(%s, %s): %s mount rc = %d", devpath, *f, - vol->mount_point, rc); -#endif - if (!rc) - break; - } - free(devpath); - - // Chmod the mount point so that its a free-for-all. - // (required for consistency with VFAT.. sigh) - if (chmod(vol->mount_point, 0777) < 0) { - LOGE("Failed to chmod %s (%s)", vol->mount_point, strerror(errno)); - return -errno; - } - - return rc; -} diff --git a/vold/volmgr_ext3.h b/vold/volmgr_ext3.h deleted file mode 100644 index bfe882a338e89677fd63af73f6264cbd89a4f948..0000000000000000000000000000000000000000 --- a/vold/volmgr_ext3.h +++ /dev/null @@ -1,27 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _VOLMGR_EXT3_H -#define _VOLMGR_EXT3_H - -#include "volmgr.h" -#include "blkdev.h" - -int ext_identify(blkdev_t *blkdev); -int ext_check(blkdev_t *blkdev); -int ext_mount(blkdev_t *blkdev, volume_t *vol, boolean safe_mode); -#endif diff --git a/vold/volmgr_vfat.c b/vold/volmgr_vfat.c deleted file mode 100644 index 1dc4c8d54ec928630c1052c27e09d9719bbe4780..0000000000000000000000000000000000000000 --- a/vold/volmgr_vfat.c +++ /dev/null @@ -1,135 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <errno.h> - -#include <sys/mount.h> - -#include "vold.h" -#include "volmgr.h" -#include "volmgr_vfat.h" -#include "logwrapper.h" - -#define VFAT_DEBUG 0 - -static char FSCK_MSDOS_PATH[] = "/system/bin/dosfsck"; - -int vfat_identify(blkdev_t *dev) -{ -#if VFAT_DEBUG - LOG_VOL("vfat_identify(%d:%d):", dev->major, dev->minor); -#endif - return 0; // XXX: Implement -} - -int vfat_check(blkdev_t *dev) -{ - int rc; - -#if VFAT_DEBUG - LOG_VOL("vfat_check(%d:%d):", dev->major, dev->minor); -#endif - - if (access(FSCK_MSDOS_PATH, X_OK)) { - LOGE("vfat_check(%d:%d): %s not found (skipping checks)", - dev->major, dev->minor, FSCK_MSDOS_PATH); - return 0; - } - -#ifdef VERIFY_PASS - char *args[7]; - args[0] = FSCK_MSDOS_PATH; - args[1] = "-v"; - args[2] = "-V"; - args[3] = "-w"; - args[4] = "-p"; - args[5] = blkdev_get_devpath(dev); - args[6] = NULL; - rc = logwrap(6, args); - free(args[5]); -#else - char *args[6]; - args[0] = FSCK_MSDOS_PATH; - args[1] = "-v"; - args[2] = "-w"; - args[3] = "-p"; - args[4] = blkdev_get_devpath(dev); - args[5] = NULL; - rc = logwrap(5, args); - free(args[4]); -#endif - - if (rc == 0) { - LOG_VOL("Filesystem check completed OK"); - return 0; - } else if (rc == 1) { - LOG_VOL("Filesystem check failed (general failure)"); - return -EINVAL; - } else if (rc == 2) { - LOG_VOL("Filesystem check failed (invalid usage)"); - return -EIO; - } else if (rc == 4) { - LOG_VOL("Filesystem check completed (errors fixed)"); - } else if (rc == 8) { - LOG_VOL("Filesystem check failed (not a FAT filesystem)"); - return -ENODATA; - } else { - LOG_VOL("Filesystem check failed (unknown exit code %d)", rc); - return -EIO; - } - return 0; -} - -int vfat_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode) -{ - int flags, rc; - char *devpath; - - devpath = blkdev_get_devpath(dev); - -#if VFAT_DEBUG - LOG_VOL("vfat_mount(%d:%d, %s, %d):", dev->major, dev->minor, vol->mount_point, safe_mode); -#endif - - flags = MS_NODEV | MS_NOEXEC | MS_NOSUID | MS_DIRSYNC; - - if (safe_mode) - flags |= MS_SYNCHRONOUS; - if (vol->state == volstate_mounted) { - LOG_VOL("Remounting %d:%d on %s, safe mode %d", dev->major, - dev->minor, vol->mount_point, safe_mode); - flags |= MS_REMOUNT; - } - - rc = mount(devpath, vol->mount_point, "vfat", flags, - "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); - - if (rc && errno == EROFS) { - LOGE("vfat_mount(%d:%d, %s): Read only filesystem - retrying mount RO", - dev->major, dev->minor, vol->mount_point); - flags |= MS_RDONLY; - rc = mount(devpath, vol->mount_point, "vfat", flags, - "utf8,uid=1000,gid=1000,fmask=711,dmask=700"); - } - -#if VFAT_DEBUG - LOG_VOL("vfat_mount(%s, %d:%d): mount rc = %d", dev->major,k dev->minor, - vol->mount_point, rc); -#endif - free (devpath); - return rc; -} diff --git a/vold/volmgr_vfat.h b/vold/volmgr_vfat.h deleted file mode 100644 index d9cf04d9b9be9cbea94d7f226a1a62d7fc7395df..0000000000000000000000000000000000000000 --- a/vold/volmgr_vfat.h +++ /dev/null @@ -1,29 +0,0 @@ - -/* - * Copyright (C) 2008 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _VOLMGR_VFAT_H -#define _VOLMGR_VFAT_H - -#include "volmgr.h" -#include "blkdev.h" - - - -int vfat_identify(blkdev_t *blkdev); -int vfat_check(blkdev_t *blkdev); -int vfat_mount(blkdev_t *blkdev, volume_t *vol, boolean safe_mode); -#endif