mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-12 11:10:07 +00:00
Today's changes.
More changes.
This commit is contained in:
parent
cb27443abf
commit
8ad517944e
73 changed files with 2865 additions and 1293 deletions
|
@ -80,6 +80,7 @@ extern int fmtfdflush(Fmt*);
|
||||||
extern int fmtstrinit(Fmt*);
|
extern int fmtstrinit(Fmt*);
|
||||||
extern char* fmtstrflush(Fmt*);
|
extern char* fmtstrflush(Fmt*);
|
||||||
extern int runefmtstrinit(Fmt*);
|
extern int runefmtstrinit(Fmt*);
|
||||||
|
extern Rune* runefmtstrflush(Fmt*);
|
||||||
|
|
||||||
extern int quotestrfmt(Fmt *f);
|
extern int quotestrfmt(Fmt *f);
|
||||||
extern void quotefmtinstall(void);
|
extern void quotefmtinstall(void);
|
||||||
|
|
876
include/lib9.h
876
include/lib9.h
|
@ -1,874 +1,2 @@
|
||||||
/*
|
#include <u.h>
|
||||||
* Lib9 is miscellany from the Plan 9 C library that doesn't
|
#include <libc.h>
|
||||||
* fit into libutf or into libfmt, but is still missing from traditional
|
|
||||||
* Unix C libraries.
|
|
||||||
*/
|
|
||||||
#ifndef _LIB9_H_
|
|
||||||
#define _LIB9_H_ 1
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define _BSD_SOURCE 1
|
|
||||||
#define _SVID_SOURCE 1
|
|
||||||
#define _XOPEN_SOURCE 1000
|
|
||||||
#define _XOPEN_SOURCE_EXTENDED 1
|
|
||||||
#define _LARGEFILE64_SOURCE 1
|
|
||||||
#define _FILE_OFFSET_BITS 64
|
|
||||||
#define __EXTENSIONS__ 1 /* SunOS */
|
|
||||||
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <assert.h>
|
|
||||||
#include <setjmp.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <utf.h>
|
|
||||||
#include <fmt.h>
|
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* OS-specific crap
|
|
||||||
*/
|
|
||||||
#define _NEEDUCHAR 1
|
|
||||||
#define _NEEDUSHORT 1
|
|
||||||
#define _NEEDUINT 1
|
|
||||||
#define _NEEDULONG 1
|
|
||||||
|
|
||||||
typedef long p9jmp_buf[sizeof(sigjmp_buf)/sizeof(long)];
|
|
||||||
|
|
||||||
#if defined(__linux__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# if defined(__USE_MISC)
|
|
||||||
# undef _NEEDUSHORT
|
|
||||||
# undef _NEEDUINT
|
|
||||||
# undef _NEEDULONG
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if defined(__sun__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# undef _NEEDUSHORT
|
|
||||||
# undef _NEEDUINT
|
|
||||||
# undef _NEEDULONG
|
|
||||||
#endif
|
|
||||||
#if defined(__FreeBSD__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# if !defined(_POSIX_SOURCE)
|
|
||||||
# undef _NEEDUSHORT
|
|
||||||
# undef _NEEDUINT
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
# include <sys/types.h>
|
|
||||||
# undef _NEEDUSHORT
|
|
||||||
# undef _NEEDUINT
|
|
||||||
# define _NEEDLL 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef signed char schar;
|
|
||||||
typedef unsigned int u32int;
|
|
||||||
#ifdef _NEEDUCHAR
|
|
||||||
typedef unsigned char uchar;
|
|
||||||
#endif
|
|
||||||
#ifdef _NEEDUSHORT
|
|
||||||
typedef unsigned short ushort;
|
|
||||||
#endif
|
|
||||||
#ifdef _NEEDUINT
|
|
||||||
typedef unsigned int uint;
|
|
||||||
#endif
|
|
||||||
#ifdef _NEEDULONG
|
|
||||||
typedef unsigned long ulong;
|
|
||||||
#endif
|
|
||||||
typedef unsigned long long uvlong;
|
|
||||||
typedef long long vlong;
|
|
||||||
typedef uvlong u64int;
|
|
||||||
typedef uchar u8int;
|
|
||||||
typedef ushort u16int;
|
|
||||||
|
|
||||||
#undef _NEEDUCHAR
|
|
||||||
#undef _NEEDUSHORT
|
|
||||||
#undef _NEEDUINT
|
|
||||||
#undef _NEEDULONG
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Begin usual libc.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define nil ((void*)0)
|
|
||||||
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
|
||||||
|
|
||||||
#ifndef offsetof
|
|
||||||
#define offsetof(s, m) (ulong)(&(((s*)0)->m))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* mem routines (provided by system <string.h>)
|
|
||||||
*
|
|
||||||
extern void* memccpy(void*, void*, int, ulong);
|
|
||||||
extern void* memset(void*, int, ulong);
|
|
||||||
extern int memcmp(void*, void*, ulong);
|
|
||||||
extern void* memcpy(void*, void*, ulong);
|
|
||||||
extern void* memmove(void*, void*, ulong);
|
|
||||||
extern void* memchr(void*, int, ulong);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* string routines (provided by system <string.h>)
|
|
||||||
*
|
|
||||||
extern char* strcat(char*, char*);
|
|
||||||
extern char* strchr(char*, int);
|
|
||||||
extern int strcmp(char*, char*);
|
|
||||||
extern char* strcpy(char*, char*);
|
|
||||||
*/
|
|
||||||
extern char* strecpy(char*, char*, char*);
|
|
||||||
/*
|
|
||||||
extern char* strdup(char*);
|
|
||||||
extern char* strncat(char*, char*, long);
|
|
||||||
extern char* strncpy(char*, char*, long);
|
|
||||||
extern int strncmp(char*, char*, long);
|
|
||||||
extern char* strpbrk(char*, char*);
|
|
||||||
extern char* strrchr(char*, int);
|
|
||||||
extern char* strtok(char*, char*);
|
|
||||||
extern long strlen(char*);
|
|
||||||
extern long strspn(char*, char*);
|
|
||||||
extern long strcspn(char*, char*);
|
|
||||||
extern char* strstr(char*, char*);
|
|
||||||
*/
|
|
||||||
extern int cistrncmp(char*, char*, int);
|
|
||||||
extern int cistrcmp(char*, char*);
|
|
||||||
extern char* cistrstr(char*, char*);
|
|
||||||
extern int tokenize(char*, char**, int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
UTFmax = 3,
|
|
||||||
Runesync = 0x80,
|
|
||||||
Runeself = 0x80,
|
|
||||||
Runeerror = 0x80,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* rune routines (provided by <utf.h>
|
|
||||||
*
|
|
||||||
extern int runetochar(char*, Rune*);
|
|
||||||
extern int chartorune(Rune*, char*);
|
|
||||||
extern int runelen(long);
|
|
||||||
extern int runenlen(Rune*, int);
|
|
||||||
extern int fullrune(char*, int);
|
|
||||||
extern int utflen(char*);
|
|
||||||
extern int utfnlen(char*, long);
|
|
||||||
extern char* utfrune(char*, long);
|
|
||||||
extern char* utfrrune(char*, long);
|
|
||||||
extern char* utfutf(char*, char*);
|
|
||||||
extern char* utfecpy(char*, char*, char*);
|
|
||||||
|
|
||||||
extern Rune* runestrcat(Rune*, Rune*);
|
|
||||||
extern Rune* runestrchr(Rune*, Rune);
|
|
||||||
extern int runestrcmp(Rune*, Rune*);
|
|
||||||
extern Rune* runestrcpy(Rune*, Rune*);
|
|
||||||
extern Rune* runestrncpy(Rune*, Rune*, long);
|
|
||||||
extern Rune* runestrecpy(Rune*, Rune*, Rune*);
|
|
||||||
extern Rune* runestrdup(Rune*);
|
|
||||||
extern Rune* runestrncat(Rune*, Rune*, long);
|
|
||||||
extern int runestrncmp(Rune*, Rune*, long);
|
|
||||||
extern Rune* runestrrchr(Rune*, Rune);
|
|
||||||
extern long runestrlen(Rune*);
|
|
||||||
extern Rune* runestrstr(Rune*, Rune*);
|
|
||||||
|
|
||||||
extern Rune tolowerrune(Rune);
|
|
||||||
extern Rune totitlerune(Rune);
|
|
||||||
extern Rune toupperrune(Rune);
|
|
||||||
extern int isalpharune(Rune);
|
|
||||||
extern int islowerrune(Rune);
|
|
||||||
extern int isspacerune(Rune);
|
|
||||||
extern int istitlerune(Rune);
|
|
||||||
extern int isupperrune(Rune);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* malloc (provied by system <stdlib.h>)
|
|
||||||
*
|
|
||||||
extern void* malloc(ulong);
|
|
||||||
*/
|
|
||||||
extern void* p9malloc(ulong);
|
|
||||||
extern void* mallocz(ulong, int);
|
|
||||||
/*
|
|
||||||
extern void free(void*);
|
|
||||||
extern ulong msize(void*);
|
|
||||||
extern void* calloc(ulong, ulong);
|
|
||||||
extern void* realloc(void*, ulong);
|
|
||||||
*/
|
|
||||||
extern void setmalloctag(void*, ulong);
|
|
||||||
extern void setrealloctag(void*, ulong);
|
|
||||||
extern ulong getmalloctag(void*);
|
|
||||||
extern ulong getrealloctag(void*);
|
|
||||||
/*
|
|
||||||
extern void* malloctopoolblock(void*);
|
|
||||||
*/
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define malloc p9malloc
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* print routines (provided by <fmt.h>)
|
|
||||||
*
|
|
||||||
typedef struct Fmt Fmt;
|
|
||||||
struct Fmt{
|
|
||||||
uchar runes;
|
|
||||||
void *start;
|
|
||||||
void *to;
|
|
||||||
void *stop;
|
|
||||||
int (*flush)(Fmt *);
|
|
||||||
void *farg;
|
|
||||||
int nfmt;
|
|
||||||
va_list args;
|
|
||||||
int r;
|
|
||||||
int width;
|
|
||||||
int prec;
|
|
||||||
ulong flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum{
|
|
||||||
FmtWidth = 1,
|
|
||||||
FmtLeft = FmtWidth << 1,
|
|
||||||
FmtPrec = FmtLeft << 1,
|
|
||||||
FmtSharp = FmtPrec << 1,
|
|
||||||
FmtSpace = FmtSharp << 1,
|
|
||||||
FmtSign = FmtSpace << 1,
|
|
||||||
FmtZero = FmtSign << 1,
|
|
||||||
FmtUnsigned = FmtZero << 1,
|
|
||||||
FmtShort = FmtUnsigned << 1,
|
|
||||||
FmtLong = FmtShort << 1,
|
|
||||||
FmtVLong = FmtLong << 1,
|
|
||||||
FmtComma = FmtVLong << 1,
|
|
||||||
FmtByte = FmtComma << 1,
|
|
||||||
|
|
||||||
FmtFlag = FmtByte << 1
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int print(char*, ...);
|
|
||||||
extern char* seprint(char*, char*, char*, ...);
|
|
||||||
extern char* vseprint(char*, char*, char*, va_list);
|
|
||||||
extern int snprint(char*, int, char*, ...);
|
|
||||||
extern int vsnprint(char*, int, char*, va_list);
|
|
||||||
extern char* smprint(char*, ...);
|
|
||||||
extern char* vsmprint(char*, va_list);
|
|
||||||
extern int sprint(char*, char*, ...);
|
|
||||||
extern int fprint(int, char*, ...);
|
|
||||||
extern int vfprint(int, char*, va_list);
|
|
||||||
|
|
||||||
extern int runesprint(Rune*, char*, ...);
|
|
||||||
extern int runesnprint(Rune*, int, char*, ...);
|
|
||||||
extern int runevsnprint(Rune*, int, char*, va_list);
|
|
||||||
extern Rune* runeseprint(Rune*, Rune*, char*, ...);
|
|
||||||
extern Rune* runevseprint(Rune*, Rune*, char*, va_list);
|
|
||||||
extern Rune* runesmprint(char*, ...);
|
|
||||||
extern Rune* runevsmprint(char*, va_list);
|
|
||||||
|
|
||||||
extern int fmtfdinit(Fmt*, int, char*, int);
|
|
||||||
extern int fmtfdflush(Fmt*);
|
|
||||||
extern int fmtstrinit(Fmt*);
|
|
||||||
extern char* fmtstrflush(Fmt*);
|
|
||||||
extern int runefmtstrinit(Fmt*);
|
|
||||||
extern Rune* runefmtstrflush(Fmt*);
|
|
||||||
|
|
||||||
extern int fmtinstall(int, int (*)(Fmt*));
|
|
||||||
extern int dofmt(Fmt*, char*);
|
|
||||||
extern int dorfmt(Fmt*, Rune*);
|
|
||||||
extern int fmtprint(Fmt*, char*, ...);
|
|
||||||
extern int fmtvprint(Fmt*, char*, va_list);
|
|
||||||
extern int fmtrune(Fmt*, int);
|
|
||||||
extern int fmtstrcpy(Fmt*, char*);
|
|
||||||
extern int fmtrunestrcpy(Fmt*, Rune*);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* error string for %r
|
|
||||||
* supplied on per os basis, not part of fmt library
|
|
||||||
*
|
|
||||||
* (provided by lib9, but declared in fmt.h)
|
|
||||||
*
|
|
||||||
extern int errfmt(Fmt *f);
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* quoted strings
|
|
||||||
*/
|
|
||||||
extern char *unquotestrdup(char*);
|
|
||||||
extern Rune *unquoterunestrdup(Rune*);
|
|
||||||
extern char *quotestrdup(char*);
|
|
||||||
extern Rune *quoterunestrdup(Rune*);
|
|
||||||
/*
|
|
||||||
* in fmt.h
|
|
||||||
*
|
|
||||||
extern void quotefmtinstall(void);
|
|
||||||
extern int quotestrfmt(Fmt*);
|
|
||||||
extern int quoterunestrfmt(Fmt*);
|
|
||||||
*/
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define doquote fmtdoquote
|
|
||||||
#endif
|
|
||||||
extern int needsrcquote(int);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* random number (in <stdlib.h>)
|
|
||||||
*
|
|
||||||
extern void srand(long);
|
|
||||||
extern int rand(void);
|
|
||||||
*/
|
|
||||||
extern int nrand(int);
|
|
||||||
extern long lrand(void);
|
|
||||||
extern long lnrand(long);
|
|
||||||
extern double frand(void);
|
|
||||||
extern ulong truerand(void); /* uses /dev/random */
|
|
||||||
extern ulong ntruerand(ulong); /* uses /dev/random */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* math
|
|
||||||
*/
|
|
||||||
extern ulong getfcr(void);
|
|
||||||
extern void setfsr(ulong);
|
|
||||||
extern ulong getfsr(void);
|
|
||||||
extern void setfcr(ulong);
|
|
||||||
extern double NaN(void);
|
|
||||||
extern double Inf(int);
|
|
||||||
extern int isNaN(double);
|
|
||||||
extern int isInf(double, int);
|
|
||||||
extern ulong umuldiv(ulong, ulong, ulong);
|
|
||||||
extern long muldiv(long, long, long);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* provided by math.h
|
|
||||||
*
|
|
||||||
extern double pow(double, double);
|
|
||||||
extern double atan2(double, double);
|
|
||||||
extern double fabs(double);
|
|
||||||
extern double atan(double);
|
|
||||||
extern double log(double);
|
|
||||||
extern double log10(double);
|
|
||||||
extern double exp(double);
|
|
||||||
extern double floor(double);
|
|
||||||
extern double ceil(double);
|
|
||||||
extern double hypot(double, double);
|
|
||||||
extern double sin(double);
|
|
||||||
extern double cos(double);
|
|
||||||
extern double tan(double);
|
|
||||||
extern double asin(double);
|
|
||||||
extern double acos(double);
|
|
||||||
extern double sinh(double);
|
|
||||||
extern double cosh(double);
|
|
||||||
extern double tanh(double);
|
|
||||||
extern double sqrt(double);
|
|
||||||
extern double fmod(double, double);
|
|
||||||
#define HUGE 3.4028234e38
|
|
||||||
#define PIO2 1.570796326794896619231e0
|
|
||||||
#define PI (PIO2+PIO2)
|
|
||||||
*/
|
|
||||||
#define PI M_PI
|
|
||||||
#define PIO2 M_PI_2
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Time-of-day
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct Tm
|
|
||||||
{
|
|
||||||
int sec;
|
|
||||||
int min;
|
|
||||||
int hour;
|
|
||||||
int mday;
|
|
||||||
int mon;
|
|
||||||
int year;
|
|
||||||
int wday;
|
|
||||||
int yday;
|
|
||||||
char zone[4];
|
|
||||||
int tzoff;
|
|
||||||
} Tm;
|
|
||||||
|
|
||||||
extern Tm* p9gmtime(long);
|
|
||||||
extern Tm* p9localtime(long);
|
|
||||||
extern char* p9asctime(Tm*);
|
|
||||||
extern char* p9ctime(long);
|
|
||||||
extern double p9cputime(void);
|
|
||||||
extern long p9times(long*);
|
|
||||||
extern long p9tm2sec(Tm*);
|
|
||||||
extern vlong p9nsec(void);
|
|
||||||
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define gmtime p9gmtime
|
|
||||||
#define localtime p9localtime
|
|
||||||
#define asctime p9asctime
|
|
||||||
#define ctime p9ctime
|
|
||||||
#define cputime p9cputime
|
|
||||||
#define times p9times
|
|
||||||
#define tm2sec p9tm2sec
|
|
||||||
#define nsec p9nsec
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* one-of-a-kind
|
|
||||||
*/
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
PNPROC = 1,
|
|
||||||
PNGROUP = 2,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* extern int abs(int); <stdlib.h> */
|
|
||||||
extern int p9atexit(void(*)(void));
|
|
||||||
extern void p9atexitdont(void(*)(void));
|
|
||||||
extern int atnotify(int(*)(void*, char*), int);
|
|
||||||
/*
|
|
||||||
* <stdlib.h>
|
|
||||||
extern double atof(char*); <stdlib.h>
|
|
||||||
extern int atoi(char*);
|
|
||||||
extern long atol(char*);
|
|
||||||
*/
|
|
||||||
extern vlong atoll(const char*);
|
|
||||||
extern double charstod(int(*)(void*), void*);
|
|
||||||
extern char* cleanname(char*);
|
|
||||||
extern int p9decrypt(void*, void*, int);
|
|
||||||
extern int p9encrypt(void*, void*, int);
|
|
||||||
extern int dec64(uchar*, int, char*, int);
|
|
||||||
extern int enc64(char*, int, uchar*, int);
|
|
||||||
extern int dec32(uchar*, int, char*, int);
|
|
||||||
extern int enc32(char*, int, uchar*, int);
|
|
||||||
extern int dec16(uchar*, int, char*, int);
|
|
||||||
extern int enc16(char*, int, uchar*, int);
|
|
||||||
extern int encodefmt(Fmt*);
|
|
||||||
extern int dirmodefmt(Fmt*);
|
|
||||||
extern void exits(char*);
|
|
||||||
extern double frexp(double, int*);
|
|
||||||
extern ulong getcallerpc(void*);
|
|
||||||
extern char* p9getenv(char*);
|
|
||||||
extern int p9putenv(char*, char*);
|
|
||||||
extern int getfields(char*, char**, int, int, char*);
|
|
||||||
extern int gettokens(char *, char **, int, char *);
|
|
||||||
extern char* getuser(void);
|
|
||||||
extern char* p9getwd(char*, int);
|
|
||||||
extern int iounit(int);
|
|
||||||
/* extern long labs(long); <math.h> */
|
|
||||||
/* extern double ldexp(double, int); <math.h> */
|
|
||||||
extern void p9longjmp(p9jmp_buf, int);
|
|
||||||
extern char* mktemp(char*);
|
|
||||||
extern int opentemp(char*);
|
|
||||||
/* extern double modf(double, double*); <math.h> */
|
|
||||||
extern int netcrypt(void*, void*);
|
|
||||||
extern void p9notejmp(void*, p9jmp_buf, int);
|
|
||||||
extern void perror(const char*);
|
|
||||||
extern int postnote(int, int, char *);
|
|
||||||
extern double pow10(int);
|
|
||||||
/* extern int putenv(char*, char*); <stdlib.h. */
|
|
||||||
/* extern void qsort(void*, long, long, int (*)(void*, void*)); <stdlib.h> */
|
|
||||||
/* extern int p9setjmp(p9jmp_buf); */
|
|
||||||
#define p9setjmp(b) sigsetjmp((void*)(b), 1)
|
|
||||||
/*
|
|
||||||
* <stdlib.h>
|
|
||||||
extern double strtod(char*, char**);
|
|
||||||
extern long strtol(char*, char**, int);
|
|
||||||
extern ulong strtoul(char*, char**, int);
|
|
||||||
extern vlong strtoll(char*, char**, int);
|
|
||||||
extern uvlong strtoull(char*, char**, int);
|
|
||||||
*/
|
|
||||||
extern void sysfatal(char*, ...);
|
|
||||||
extern void p9syslog(int, char*, char*, ...);
|
|
||||||
extern long time(long*);
|
|
||||||
/* extern int tolower(int); <ctype.h> */
|
|
||||||
/* extern int toupper(int); <ctype.h> */
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define atexit p9atexit
|
|
||||||
#define atexitdont p9atexitdont
|
|
||||||
#define encrypt p9encrypt
|
|
||||||
#define decrypt p9decrypt
|
|
||||||
#define getenv p9getenv
|
|
||||||
#define getwd p9getwd
|
|
||||||
#define longjmp p9longjmp
|
|
||||||
#undef setjmp
|
|
||||||
#define setjmp p9setjmp
|
|
||||||
#define putenv p9putenv
|
|
||||||
#define notejmp p9notejmp
|
|
||||||
#define jmp_buf p9jmp_buf
|
|
||||||
#define syslog p9syslog
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* synchronization
|
|
||||||
*/
|
|
||||||
typedef
|
|
||||||
struct Lock {
|
|
||||||
int val;
|
|
||||||
} Lock;
|
|
||||||
|
|
||||||
extern int _tas(int*);
|
|
||||||
|
|
||||||
extern void lock(Lock*);
|
|
||||||
extern void unlock(Lock*);
|
|
||||||
extern int canlock(Lock*);
|
|
||||||
|
|
||||||
typedef struct QLp QLp;
|
|
||||||
struct QLp
|
|
||||||
{
|
|
||||||
int inuse;
|
|
||||||
QLp *next;
|
|
||||||
char state;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct QLock
|
|
||||||
{
|
|
||||||
Lock lock;
|
|
||||||
int locked;
|
|
||||||
QLp *head;
|
|
||||||
QLp *tail;
|
|
||||||
} QLock;
|
|
||||||
|
|
||||||
extern void qlock(QLock*);
|
|
||||||
extern void qunlock(QLock*);
|
|
||||||
extern int canqlock(QLock*);
|
|
||||||
extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct RWLock
|
|
||||||
{
|
|
||||||
Lock lock;
|
|
||||||
int readers; /* number of readers */
|
|
||||||
int writer; /* number of writers */
|
|
||||||
QLp *head; /* list of waiting processes */
|
|
||||||
QLp *tail;
|
|
||||||
} RWLock;
|
|
||||||
|
|
||||||
extern void rlock(RWLock*);
|
|
||||||
extern void runlock(RWLock*);
|
|
||||||
extern int canrlock(RWLock*);
|
|
||||||
extern void wlock(RWLock*);
|
|
||||||
extern void wunlock(RWLock*);
|
|
||||||
extern int canwlock(RWLock*);
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct Rendez
|
|
||||||
{
|
|
||||||
QLock *l;
|
|
||||||
QLp *head;
|
|
||||||
QLp *tail;
|
|
||||||
} Rendez;
|
|
||||||
|
|
||||||
extern void rsleep(Rendez*); /* unlocks r->l, sleeps, locks r->l again */
|
|
||||||
extern int rwakeup(Rendez*);
|
|
||||||
extern int rwakeupall(Rendez*);
|
|
||||||
extern void** privalloc(void);
|
|
||||||
extern void privfree(void**);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* network dialing
|
|
||||||
*/
|
|
||||||
#define NETPATHLEN 40
|
|
||||||
extern int p9accept(int, char*);
|
|
||||||
extern int p9announce(char*, char*);
|
|
||||||
extern int p9dial(char*, char*, char*, int*);
|
|
||||||
extern void p9setnetmtpt(char*, int, char*);
|
|
||||||
extern int p9hangup(int);
|
|
||||||
extern int p9listen(char*, char*);
|
|
||||||
extern char* p9netmkaddr(char*, char*, char*);
|
|
||||||
extern int p9reject(int, char*, char*);
|
|
||||||
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define accept p9accept
|
|
||||||
#define announce p9announce
|
|
||||||
#define dial p9dial
|
|
||||||
#define setnetmtpt p9setnetmtpt
|
|
||||||
#define hangup p9hangup
|
|
||||||
#define listen p9listen
|
|
||||||
#define netmkaddr p9netmkaddr
|
|
||||||
#define reject p9reject
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* encryption
|
|
||||||
*/
|
|
||||||
extern int pushssl(int, char*, char*, char*, int*);
|
|
||||||
extern int pushtls(int, char*, char*, int, char*, char*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* network services
|
|
||||||
*/
|
|
||||||
typedef struct NetConnInfo NetConnInfo;
|
|
||||||
struct NetConnInfo
|
|
||||||
{
|
|
||||||
char *dir; /* connection directory */
|
|
||||||
char *root; /* network root */
|
|
||||||
char *spec; /* binding spec */
|
|
||||||
char *lsys; /* local system */
|
|
||||||
char *lserv; /* local service */
|
|
||||||
char *rsys; /* remote system */
|
|
||||||
char *rserv; /* remote service */
|
|
||||||
};
|
|
||||||
extern NetConnInfo* getnetconninfo(char*, int);
|
|
||||||
extern void freenetconninfo(NetConnInfo*);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* system calls
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#define STATMAX 65535U /* max length of machine-independent stat structure */
|
|
||||||
#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
|
|
||||||
#define ERRMAX 128 /* max length of error string */
|
|
||||||
|
|
||||||
#define MORDER 0x0003 /* mask for bits defining order of mounting */
|
|
||||||
#define MREPL 0x0000 /* mount replaces object */
|
|
||||||
#define MBEFORE 0x0001 /* mount goes before others in union directory */
|
|
||||||
#define MAFTER 0x0002 /* mount goes after others in union directory */
|
|
||||||
#define MCREATE 0x0004 /* permit creation in mounted directory */
|
|
||||||
#define MCACHE 0x0010 /* cache some data */
|
|
||||||
#define MMASK 0x0017 /* all bits on */
|
|
||||||
|
|
||||||
#define OREAD 0 /* open for read */
|
|
||||||
#define OWRITE 1 /* write */
|
|
||||||
#define ORDWR 2 /* read and write */
|
|
||||||
#define OEXEC 3 /* execute, == read but check execute permission */
|
|
||||||
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
|
|
||||||
#define OCEXEC 32 /* or'ed in, close on exec */
|
|
||||||
#define ORCLOSE 64 /* or'ed in, remove on close */
|
|
||||||
#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
|
|
||||||
|
|
||||||
#define AEXIST 0 /* accessible: exists */
|
|
||||||
#define AEXEC 1 /* execute access */
|
|
||||||
#define AWRITE 2 /* write access */
|
|
||||||
#define AREAD 4 /* read access */
|
|
||||||
|
|
||||||
/* Segattch */
|
|
||||||
#define SG_RONLY 0040 /* read only */
|
|
||||||
#define SG_CEXEC 0100 /* detach on exec */
|
|
||||||
|
|
||||||
#define NCONT 0 /* continue after note */
|
|
||||||
#define NDFLT 1 /* terminate after note */
|
|
||||||
#define NSAVE 2 /* clear note but hold state */
|
|
||||||
#define NRSTR 3 /* restore saved state */
|
|
||||||
|
|
||||||
/* bits in Qid.type */
|
|
||||||
#define QTDIR 0x80 /* type bit for directories */
|
|
||||||
#define QTAPPEND 0x40 /* type bit for append only files */
|
|
||||||
#define QTEXCL 0x20 /* type bit for exclusive use files */
|
|
||||||
#define QTMOUNT 0x10 /* type bit for mounted channel */
|
|
||||||
#define QTAUTH 0x08 /* type bit for authentication file */
|
|
||||||
#define QTFILE 0x00 /* plain file */
|
|
||||||
|
|
||||||
/* bits in Dir.mode */
|
|
||||||
#define DMDIR 0x80000000 /* mode bit for directories */
|
|
||||||
#define DMAPPEND 0x40000000 /* mode bit for append only files */
|
|
||||||
#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
|
|
||||||
#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
|
|
||||||
#define DMAUTH 0x08000000 /* mode bit for authentication file */
|
|
||||||
#define DMREAD 0x4 /* mode bit for read permission */
|
|
||||||
#define DMWRITE 0x2 /* mode bit for write permission */
|
|
||||||
#define DMEXEC 0x1 /* mode bit for execute permission */
|
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
|
||||||
#undef RFFDG
|
|
||||||
#undef RFNOTEG
|
|
||||||
#undef RFPROC
|
|
||||||
#undef RFMEM
|
|
||||||
#undef RFNOWAIT
|
|
||||||
#undef RFCFDG
|
|
||||||
#undef RFNAMEG
|
|
||||||
#undef RFENVG
|
|
||||||
#undef RFCENVG
|
|
||||||
#undef RFCFDG
|
|
||||||
#undef RFCNAMEG
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
RFNAMEG = (1<<0),
|
|
||||||
RFENVG = (1<<1),
|
|
||||||
RFFDG = (1<<2),
|
|
||||||
RFNOTEG = (1<<3),
|
|
||||||
RFPROC = (1<<4),
|
|
||||||
RFMEM = (1<<5),
|
|
||||||
RFNOWAIT = (1<<6),
|
|
||||||
RFCNAMEG = (1<<10),
|
|
||||||
RFCENVG = (1<<11),
|
|
||||||
RFCFDG = (1<<12),
|
|
||||||
/* RFREND = (1<<13), */
|
|
||||||
/* RFNOMNT = (1<<14) */
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int ffork(int, void(*)(void*), void*);
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct Qid
|
|
||||||
{
|
|
||||||
uvlong path;
|
|
||||||
ulong vers;
|
|
||||||
uchar type;
|
|
||||||
} Qid;
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct Dir {
|
|
||||||
/* system-modified data */
|
|
||||||
ushort type; /* server type */
|
|
||||||
uint dev; /* server subtype */
|
|
||||||
/* file data */
|
|
||||||
Qid qid; /* unique id from server */
|
|
||||||
ulong mode; /* permissions */
|
|
||||||
ulong atime; /* last read time */
|
|
||||||
ulong mtime; /* last write time */
|
|
||||||
vlong length; /* file length */
|
|
||||||
char *name; /* last element of path */
|
|
||||||
char *uid; /* owner name */
|
|
||||||
char *gid; /* group name */
|
|
||||||
char *muid; /* last modifier name */
|
|
||||||
} Dir;
|
|
||||||
|
|
||||||
/* keep /sys/src/ape/lib/ap/plan9/sys9.h in sync with this -rsc */
|
|
||||||
typedef
|
|
||||||
struct Waitmsg
|
|
||||||
{
|
|
||||||
int pid; /* of loved one */
|
|
||||||
ulong time[3]; /* of loved one & descendants */
|
|
||||||
char *msg;
|
|
||||||
} Waitmsg;
|
|
||||||
|
|
||||||
typedef
|
|
||||||
struct IOchunk
|
|
||||||
{
|
|
||||||
void *addr;
|
|
||||||
ulong len;
|
|
||||||
} IOchunk;
|
|
||||||
|
|
||||||
extern void _exits(char*);
|
|
||||||
|
|
||||||
extern void abort(void);
|
|
||||||
extern int p9access(char*, int);
|
|
||||||
extern long p9alarm(ulong);
|
|
||||||
extern int await(char*, int);
|
|
||||||
extern int awaitnohang(char*, int);
|
|
||||||
/* extern int bind(char*, char*, int); give up */
|
|
||||||
/* extern int brk(void*); <unistd.h> */
|
|
||||||
extern int p9chdir(char*);
|
|
||||||
extern int close(int);
|
|
||||||
extern int p9create(char*, int, ulong);
|
|
||||||
extern int p9dup(int, int);
|
|
||||||
extern int errstr(char*, uint);
|
|
||||||
extern int p9exec(char*, char*[]);
|
|
||||||
/* extern int execl(char*, ...); <unistd.h> */
|
|
||||||
/* extern int fork(void); <unistd.h> */
|
|
||||||
extern int p9rfork(int);
|
|
||||||
/* not implemented
|
|
||||||
extern int fauth(int, char*);
|
|
||||||
extern int fstat(int, uchar*, int);
|
|
||||||
extern int fwstat(int, uchar*, int);
|
|
||||||
extern int fversion(int, int, char*, int);
|
|
||||||
extern int mount(int, int, char*, int, char*);
|
|
||||||
extern int unmount(char*, char*);
|
|
||||||
*/
|
|
||||||
extern int noted(int);
|
|
||||||
extern int notify(void(*)(void*, char*));
|
|
||||||
extern int p9open(char*, int);
|
|
||||||
extern int fd2path(int, char*, int);
|
|
||||||
extern int p9pipe(int*);
|
|
||||||
/*
|
|
||||||
* use defs from <unistd.h>
|
|
||||||
extern long pread(int, void*, long, vlong);
|
|
||||||
extern long preadv(int, IOchunk*, int, vlong);
|
|
||||||
extern long pwrite(int, void*, long, vlong);
|
|
||||||
extern long pwritev(int, IOchunk*, int, vlong);
|
|
||||||
extern long read(int, void*, long);
|
|
||||||
*/
|
|
||||||
extern long readn(int, void*, long);
|
|
||||||
/* extern long readv(int, IOchunk*, int); <unistd.h> */
|
|
||||||
extern int remove(const char*);
|
|
||||||
/* extern void* sbrk(ulong); <unistd.h> */
|
|
||||||
/* extern long oseek(int, long, int); */
|
|
||||||
extern vlong p9seek(int, vlong, int);
|
|
||||||
/* give up
|
|
||||||
extern long segattach(int, char*, void*, ulong);
|
|
||||||
extern int segbrk(void*, void*);
|
|
||||||
extern int segdetach(void*);
|
|
||||||
extern int segflush(void*, ulong);
|
|
||||||
extern int segfree(void*, ulong);
|
|
||||||
*/
|
|
||||||
extern int p9sleep(long);
|
|
||||||
/* extern int stat(char*, uchar*, int); give up */
|
|
||||||
extern Waitmsg* p9wait(void);
|
|
||||||
extern Waitmsg* waitnohang(void);
|
|
||||||
extern int p9waitpid(void);
|
|
||||||
/* <unistd.h>
|
|
||||||
extern long write(int, void*, long);
|
|
||||||
extern long writev(int, IOchunk*, int);
|
|
||||||
*/
|
|
||||||
/* extern int wstat(char*, uchar*, int); give up */
|
|
||||||
extern ulong rendezvous(ulong, ulong);
|
|
||||||
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define alarm p9alarm
|
|
||||||
#define dup p9dup
|
|
||||||
#define exec p9exec
|
|
||||||
#define seek p9seek
|
|
||||||
#define sleep p9sleep
|
|
||||||
#define wait p9wait
|
|
||||||
#define waitpid p9waitpid
|
|
||||||
#define rfork p9rfork
|
|
||||||
#define access p9access
|
|
||||||
#define create p9create
|
|
||||||
#define open p9open
|
|
||||||
#define pipe p9pipe
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern Dir* dirstat(char*);
|
|
||||||
extern Dir* dirfstat(int);
|
|
||||||
extern int dirwstat(char*, Dir*);
|
|
||||||
extern int dirfwstat(int, Dir*);
|
|
||||||
extern long dirread(int, Dir**);
|
|
||||||
extern void nulldir(Dir*);
|
|
||||||
extern long dirreadall(int, Dir**);
|
|
||||||
/* extern int getpid(void); <unistd.h> */
|
|
||||||
/* extern int getppid(void); */
|
|
||||||
extern void rerrstr(char*, uint);
|
|
||||||
extern char* sysname(void);
|
|
||||||
extern void werrstr(char*, ...);
|
|
||||||
extern char* getns(void);
|
|
||||||
extern int sendfd(int, int);
|
|
||||||
extern int recvfd(int);
|
|
||||||
extern int post9pservice(int, char*);
|
|
||||||
|
|
||||||
/* external names that we don't want to step on */
|
|
||||||
#ifndef NOPLAN9DEFINES
|
|
||||||
#define main p9main
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* compiler directives on plan 9 */
|
|
||||||
#define USED(x) if(x){}else{}
|
|
||||||
#define SET(x) ((x)=0)
|
|
||||||
|
|
||||||
/* command line */
|
|
||||||
extern char *argv0;
|
|
||||||
extern void __fixargv0(void);
|
|
||||||
#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\
|
|
||||||
argv[0] && argv[0][0]=='-' && argv[0][1];\
|
|
||||||
argc--, argv++) {\
|
|
||||||
char *_args, *_argt;\
|
|
||||||
Rune _argc;\
|
|
||||||
_args = &argv[0][1];\
|
|
||||||
if(_args[0]=='-' && _args[1]==0){\
|
|
||||||
argc--; argv++; break;\
|
|
||||||
}\
|
|
||||||
_argc = 0;\
|
|
||||||
while(*_args && (_args += chartorune(&_argc, _args)))\
|
|
||||||
switch(_argc)
|
|
||||||
#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
|
|
||||||
#define ARGF() (_argt=_args, _args="",\
|
|
||||||
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
|
|
||||||
#define EARGF(x) (_argt=_args, _args="",\
|
|
||||||
(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
|
|
||||||
|
|
||||||
#define ARGC() _argc
|
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /* _LIB9_H_ */
|
|
||||||
|
|
|
@ -43,4 +43,4 @@ typedef struct Sinstack Sinstack;
|
||||||
extern char *s_rdinstack(Sinstack*, String*);
|
extern char *s_rdinstack(Sinstack*, String*);
|
||||||
extern Sinstack *s_allocinstack(char*);
|
extern Sinstack *s_allocinstack(char*);
|
||||||
extern void s_freeinstack(Sinstack*);
|
extern void s_freeinstack(Sinstack*);
|
||||||
#endif BGETC
|
#endif /* BGETC */
|
||||||
|
|
794
include/libc.h
794
include/libc.h
|
@ -1,2 +1,794 @@
|
||||||
#include <lib9.h>
|
/*
|
||||||
|
* Lib9 is miscellany from the Plan 9 C library that doesn't
|
||||||
|
* fit into libutf or into libfmt, but is still missing from traditional
|
||||||
|
* Unix C libraries.
|
||||||
|
*/
|
||||||
|
#ifndef _LIBC_H_
|
||||||
|
#define _LIBC_H_ 1
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Begin usual libc.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define nil ((void*)0)
|
||||||
|
#define nelem(x) (sizeof(x)/sizeof((x)[0]))
|
||||||
|
|
||||||
|
#ifndef offsetof
|
||||||
|
#define offsetof(s, m) (ulong)(&(((s*)0)->m))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mem routines (provided by system <string.h>)
|
||||||
|
*
|
||||||
|
extern void* memccpy(void*, void*, int, ulong);
|
||||||
|
extern void* memset(void*, int, ulong);
|
||||||
|
extern int memcmp(void*, void*, ulong);
|
||||||
|
extern void* memcpy(void*, void*, ulong);
|
||||||
|
extern void* memmove(void*, void*, ulong);
|
||||||
|
extern void* memchr(void*, int, ulong);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* string routines (provided by system <string.h>)
|
||||||
|
*
|
||||||
|
extern char* strcat(char*, char*);
|
||||||
|
extern char* strchr(char*, int);
|
||||||
|
extern int strcmp(char*, char*);
|
||||||
|
extern char* strcpy(char*, char*);
|
||||||
|
*/
|
||||||
|
extern char* strecpy(char*, char*, char*);
|
||||||
|
/*
|
||||||
|
extern char* strdup(char*);
|
||||||
|
extern char* strncat(char*, char*, long);
|
||||||
|
extern char* strncpy(char*, char*, long);
|
||||||
|
extern int strncmp(char*, char*, long);
|
||||||
|
extern char* strpbrk(char*, char*);
|
||||||
|
extern char* strrchr(char*, int);
|
||||||
|
extern char* strtok(char*, char*);
|
||||||
|
extern long strlen(char*);
|
||||||
|
extern long strspn(char*, char*);
|
||||||
|
extern long strcspn(char*, char*);
|
||||||
|
extern char* strstr(char*, char*);
|
||||||
|
*/
|
||||||
|
extern int cistrncmp(char*, char*, int);
|
||||||
|
extern int cistrcmp(char*, char*);
|
||||||
|
extern char* cistrstr(char*, char*);
|
||||||
|
extern int tokenize(char*, char**, int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
UTFmax = 3,
|
||||||
|
Runesync = 0x80,
|
||||||
|
Runeself = 0x80,
|
||||||
|
Runeerror = 0x80,
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rune routines (provided by <utf.h>
|
||||||
|
*
|
||||||
|
extern int runetochar(char*, Rune*);
|
||||||
|
extern int chartorune(Rune*, char*);
|
||||||
|
extern int runelen(long);
|
||||||
|
extern int runenlen(Rune*, int);
|
||||||
|
extern int fullrune(char*, int);
|
||||||
|
extern int utflen(char*);
|
||||||
|
extern int utfnlen(char*, long);
|
||||||
|
extern char* utfrune(char*, long);
|
||||||
|
extern char* utfrrune(char*, long);
|
||||||
|
extern char* utfutf(char*, char*);
|
||||||
|
extern char* utfecpy(char*, char*, char*);
|
||||||
|
|
||||||
|
extern Rune* runestrcat(Rune*, Rune*);
|
||||||
|
extern Rune* runestrchr(Rune*, Rune);
|
||||||
|
extern int runestrcmp(Rune*, Rune*);
|
||||||
|
extern Rune* runestrcpy(Rune*, Rune*);
|
||||||
|
extern Rune* runestrncpy(Rune*, Rune*, long);
|
||||||
|
extern Rune* runestrecpy(Rune*, Rune*, Rune*);
|
||||||
|
extern Rune* runestrdup(Rune*);
|
||||||
|
extern Rune* runestrncat(Rune*, Rune*, long);
|
||||||
|
extern int runestrncmp(Rune*, Rune*, long);
|
||||||
|
extern Rune* runestrrchr(Rune*, Rune);
|
||||||
|
extern long runestrlen(Rune*);
|
||||||
|
extern Rune* runestrstr(Rune*, Rune*);
|
||||||
|
|
||||||
|
extern Rune tolowerrune(Rune);
|
||||||
|
extern Rune totitlerune(Rune);
|
||||||
|
extern Rune toupperrune(Rune);
|
||||||
|
extern int isalpharune(Rune);
|
||||||
|
extern int islowerrune(Rune);
|
||||||
|
extern int isspacerune(Rune);
|
||||||
|
extern int istitlerune(Rune);
|
||||||
|
extern int isupperrune(Rune);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* malloc (provied by system <stdlib.h>)
|
||||||
|
*
|
||||||
|
extern void* malloc(ulong);
|
||||||
|
*/
|
||||||
|
extern void* p9malloc(ulong);
|
||||||
|
extern void* mallocz(ulong, int);
|
||||||
|
/*
|
||||||
|
extern void free(void*);
|
||||||
|
extern ulong msize(void*);
|
||||||
|
extern void* calloc(ulong, ulong);
|
||||||
|
extern void* realloc(void*, ulong);
|
||||||
|
*/
|
||||||
|
extern void setmalloctag(void*, ulong);
|
||||||
|
extern void setrealloctag(void*, ulong);
|
||||||
|
extern ulong getmalloctag(void*);
|
||||||
|
extern ulong getrealloctag(void*);
|
||||||
|
/*
|
||||||
|
extern void* malloctopoolblock(void*);
|
||||||
|
*/
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define malloc p9malloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* print routines (provided by <fmt.h>)
|
||||||
|
*
|
||||||
|
typedef struct Fmt Fmt;
|
||||||
|
struct Fmt{
|
||||||
|
uchar runes;
|
||||||
|
void *start;
|
||||||
|
void *to;
|
||||||
|
void *stop;
|
||||||
|
int (*flush)(Fmt *);
|
||||||
|
void *farg;
|
||||||
|
int nfmt;
|
||||||
|
va_list args;
|
||||||
|
int r;
|
||||||
|
int width;
|
||||||
|
int prec;
|
||||||
|
ulong flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum{
|
||||||
|
FmtWidth = 1,
|
||||||
|
FmtLeft = FmtWidth << 1,
|
||||||
|
FmtPrec = FmtLeft << 1,
|
||||||
|
FmtSharp = FmtPrec << 1,
|
||||||
|
FmtSpace = FmtSharp << 1,
|
||||||
|
FmtSign = FmtSpace << 1,
|
||||||
|
FmtZero = FmtSign << 1,
|
||||||
|
FmtUnsigned = FmtZero << 1,
|
||||||
|
FmtShort = FmtUnsigned << 1,
|
||||||
|
FmtLong = FmtShort << 1,
|
||||||
|
FmtVLong = FmtLong << 1,
|
||||||
|
FmtComma = FmtVLong << 1,
|
||||||
|
FmtByte = FmtComma << 1,
|
||||||
|
|
||||||
|
FmtFlag = FmtByte << 1
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int print(char*, ...);
|
||||||
|
extern char* seprint(char*, char*, char*, ...);
|
||||||
|
extern char* vseprint(char*, char*, char*, va_list);
|
||||||
|
extern int snprint(char*, int, char*, ...);
|
||||||
|
extern int vsnprint(char*, int, char*, va_list);
|
||||||
|
extern char* smprint(char*, ...);
|
||||||
|
extern char* vsmprint(char*, va_list);
|
||||||
|
extern int sprint(char*, char*, ...);
|
||||||
|
extern int fprint(int, char*, ...);
|
||||||
|
extern int vfprint(int, char*, va_list);
|
||||||
|
|
||||||
|
extern int runesprint(Rune*, char*, ...);
|
||||||
|
extern int runesnprint(Rune*, int, char*, ...);
|
||||||
|
extern int runevsnprint(Rune*, int, char*, va_list);
|
||||||
|
extern Rune* runeseprint(Rune*, Rune*, char*, ...);
|
||||||
|
extern Rune* runevseprint(Rune*, Rune*, char*, va_list);
|
||||||
|
extern Rune* runesmprint(char*, ...);
|
||||||
|
extern Rune* runevsmprint(char*, va_list);
|
||||||
|
|
||||||
|
extern int fmtfdinit(Fmt*, int, char*, int);
|
||||||
|
extern int fmtfdflush(Fmt*);
|
||||||
|
extern int fmtstrinit(Fmt*);
|
||||||
|
extern char* fmtstrflush(Fmt*);
|
||||||
|
extern int runefmtstrinit(Fmt*);
|
||||||
|
extern Rune* runefmtstrflush(Fmt*);
|
||||||
|
|
||||||
|
extern int fmtinstall(int, int (*)(Fmt*));
|
||||||
|
extern int dofmt(Fmt*, char*);
|
||||||
|
extern int dorfmt(Fmt*, Rune*);
|
||||||
|
extern int fmtprint(Fmt*, char*, ...);
|
||||||
|
extern int fmtvprint(Fmt*, char*, va_list);
|
||||||
|
extern int fmtrune(Fmt*, int);
|
||||||
|
extern int fmtstrcpy(Fmt*, char*);
|
||||||
|
extern int fmtrunestrcpy(Fmt*, Rune*);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* error string for %r
|
||||||
|
* supplied on per os basis, not part of fmt library
|
||||||
|
*
|
||||||
|
* (provided by lib9, but declared in fmt.h)
|
||||||
|
*
|
||||||
|
extern int errfmt(Fmt *f);
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* quoted strings
|
||||||
|
*/
|
||||||
|
extern char *unquotestrdup(char*);
|
||||||
|
extern Rune *unquoterunestrdup(Rune*);
|
||||||
|
extern char *quotestrdup(char*);
|
||||||
|
extern Rune *quoterunestrdup(Rune*);
|
||||||
|
/*
|
||||||
|
* in fmt.h
|
||||||
|
*
|
||||||
|
extern void quotefmtinstall(void);
|
||||||
|
extern int quotestrfmt(Fmt*);
|
||||||
|
extern int quoterunestrfmt(Fmt*);
|
||||||
|
*/
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define doquote fmtdoquote
|
||||||
|
#endif
|
||||||
|
extern int needsrcquote(int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* random number (in <stdlib.h>)
|
||||||
|
*
|
||||||
|
extern void srand(long);
|
||||||
|
extern int rand(void);
|
||||||
|
*/
|
||||||
|
extern int nrand(int);
|
||||||
|
extern long lrand(void);
|
||||||
|
extern long lnrand(long);
|
||||||
|
extern double frand(void);
|
||||||
|
extern ulong truerand(void); /* uses /dev/random */
|
||||||
|
extern ulong ntruerand(ulong); /* uses /dev/random */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* math
|
||||||
|
*/
|
||||||
|
extern ulong getfcr(void);
|
||||||
|
extern void setfsr(ulong);
|
||||||
|
extern ulong getfsr(void);
|
||||||
|
extern void setfcr(ulong);
|
||||||
|
extern double NaN(void);
|
||||||
|
extern double Inf(int);
|
||||||
|
extern int isNaN(double);
|
||||||
|
extern int isInf(double, int);
|
||||||
|
extern ulong umuldiv(ulong, ulong, ulong);
|
||||||
|
extern long muldiv(long, long, long);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* provided by math.h
|
||||||
|
*
|
||||||
|
extern double pow(double, double);
|
||||||
|
extern double atan2(double, double);
|
||||||
|
extern double fabs(double);
|
||||||
|
extern double atan(double);
|
||||||
|
extern double log(double);
|
||||||
|
extern double log10(double);
|
||||||
|
extern double exp(double);
|
||||||
|
extern double floor(double);
|
||||||
|
extern double ceil(double);
|
||||||
|
extern double hypot(double, double);
|
||||||
|
extern double sin(double);
|
||||||
|
extern double cos(double);
|
||||||
|
extern double tan(double);
|
||||||
|
extern double asin(double);
|
||||||
|
extern double acos(double);
|
||||||
|
extern double sinh(double);
|
||||||
|
extern double cosh(double);
|
||||||
|
extern double tanh(double);
|
||||||
|
extern double sqrt(double);
|
||||||
|
extern double fmod(double, double);
|
||||||
|
#define HUGE 3.4028234e38
|
||||||
|
#define PIO2 1.570796326794896619231e0
|
||||||
|
#define PI (PIO2+PIO2)
|
||||||
|
*/
|
||||||
|
#define PI M_PI
|
||||||
|
#define PIO2 M_PI_2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Time-of-day
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct Tm
|
||||||
|
{
|
||||||
|
int sec;
|
||||||
|
int min;
|
||||||
|
int hour;
|
||||||
|
int mday;
|
||||||
|
int mon;
|
||||||
|
int year;
|
||||||
|
int wday;
|
||||||
|
int yday;
|
||||||
|
char zone[4];
|
||||||
|
int tzoff;
|
||||||
|
} Tm;
|
||||||
|
|
||||||
|
extern Tm* p9gmtime(long);
|
||||||
|
extern Tm* p9localtime(long);
|
||||||
|
extern char* p9asctime(Tm*);
|
||||||
|
extern char* p9ctime(long);
|
||||||
|
extern double p9cputime(void);
|
||||||
|
extern long p9times(long*);
|
||||||
|
extern long p9tm2sec(Tm*);
|
||||||
|
extern vlong p9nsec(void);
|
||||||
|
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define gmtime p9gmtime
|
||||||
|
#define localtime p9localtime
|
||||||
|
#define asctime p9asctime
|
||||||
|
#define ctime p9ctime
|
||||||
|
#define cputime p9cputime
|
||||||
|
#define times p9times
|
||||||
|
#define tm2sec p9tm2sec
|
||||||
|
#define nsec p9nsec
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* one-of-a-kind
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PNPROC = 1,
|
||||||
|
PNGROUP = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* extern int abs(int); <stdlib.h> */
|
||||||
|
extern int p9atexit(void(*)(void));
|
||||||
|
extern void p9atexitdont(void(*)(void));
|
||||||
|
extern int atnotify(int(*)(void*, char*), int);
|
||||||
|
/*
|
||||||
|
* <stdlib.h>
|
||||||
|
extern double atof(char*); <stdlib.h>
|
||||||
|
extern int atoi(char*);
|
||||||
|
extern long atol(char*);
|
||||||
|
*/
|
||||||
|
extern vlong atoll(const char*);
|
||||||
|
extern double charstod(int(*)(void*), void*);
|
||||||
|
extern char* cleanname(char*);
|
||||||
|
extern int p9decrypt(void*, void*, int);
|
||||||
|
extern int p9encrypt(void*, void*, int);
|
||||||
|
extern int dec64(uchar*, int, char*, int);
|
||||||
|
extern int enc64(char*, int, uchar*, int);
|
||||||
|
extern int dec32(uchar*, int, char*, int);
|
||||||
|
extern int enc32(char*, int, uchar*, int);
|
||||||
|
extern int dec16(uchar*, int, char*, int);
|
||||||
|
extern int enc16(char*, int, uchar*, int);
|
||||||
|
extern int encodefmt(Fmt*);
|
||||||
|
extern int dirmodefmt(Fmt*);
|
||||||
|
extern void exits(char*);
|
||||||
|
extern double frexp(double, int*);
|
||||||
|
extern ulong getcallerpc(void*);
|
||||||
|
extern char* p9getenv(char*);
|
||||||
|
extern int p9putenv(char*, char*);
|
||||||
|
extern int getfields(char*, char**, int, int, char*);
|
||||||
|
extern int gettokens(char *, char **, int, char *);
|
||||||
|
extern char* getuser(void);
|
||||||
|
extern char* p9getwd(char*, int);
|
||||||
|
extern int iounit(int);
|
||||||
|
/* extern long labs(long); <math.h> */
|
||||||
|
/* extern double ldexp(double, int); <math.h> */
|
||||||
|
extern void p9longjmp(p9jmp_buf, int);
|
||||||
|
extern char* mktemp(char*);
|
||||||
|
extern int opentemp(char*);
|
||||||
|
/* extern double modf(double, double*); <math.h> */
|
||||||
|
extern int netcrypt(void*, void*);
|
||||||
|
extern void p9notejmp(void*, p9jmp_buf, int);
|
||||||
|
extern void perror(const char*);
|
||||||
|
extern int postnote(int, int, char *);
|
||||||
|
extern double pow10(int);
|
||||||
|
/* extern int putenv(char*, char*); <stdlib.h. */
|
||||||
|
/* extern void qsort(void*, long, long, int (*)(void*, void*)); <stdlib.h> */
|
||||||
|
/* extern int p9setjmp(p9jmp_buf); */
|
||||||
|
#define p9setjmp(b) sigsetjmp((void*)(b), 1)
|
||||||
|
/*
|
||||||
|
* <stdlib.h>
|
||||||
|
extern double strtod(char*, char**);
|
||||||
|
extern long strtol(char*, char**, int);
|
||||||
|
extern ulong strtoul(char*, char**, int);
|
||||||
|
extern vlong strtoll(char*, char**, int);
|
||||||
|
extern uvlong strtoull(char*, char**, int);
|
||||||
|
*/
|
||||||
|
extern void sysfatal(char*, ...);
|
||||||
|
extern void p9syslog(int, char*, char*, ...);
|
||||||
|
extern long p9time(long*);
|
||||||
|
/* extern int tolower(int); <ctype.h> */
|
||||||
|
/* extern int toupper(int); <ctype.h> */
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define atexit p9atexit
|
||||||
|
#define atexitdont p9atexitdont
|
||||||
|
#define encrypt p9encrypt
|
||||||
|
#define decrypt p9decrypt
|
||||||
|
#define getenv p9getenv
|
||||||
|
#define getwd p9getwd
|
||||||
|
#define longjmp p9longjmp
|
||||||
|
#undef setjmp
|
||||||
|
#define setjmp p9setjmp
|
||||||
|
#define putenv p9putenv
|
||||||
|
#define notejmp p9notejmp
|
||||||
|
#define jmp_buf p9jmp_buf
|
||||||
|
#define syslog p9syslog
|
||||||
|
#define time p9time
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* synchronization
|
||||||
|
*/
|
||||||
|
typedef
|
||||||
|
struct Lock {
|
||||||
|
int val;
|
||||||
|
} Lock;
|
||||||
|
|
||||||
|
extern int _tas(int*);
|
||||||
|
|
||||||
|
extern void lock(Lock*);
|
||||||
|
extern void unlock(Lock*);
|
||||||
|
extern int canlock(Lock*);
|
||||||
|
|
||||||
|
typedef struct QLp QLp;
|
||||||
|
struct QLp
|
||||||
|
{
|
||||||
|
int inuse;
|
||||||
|
QLp *next;
|
||||||
|
char state;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct QLock
|
||||||
|
{
|
||||||
|
Lock lock;
|
||||||
|
int locked;
|
||||||
|
QLp *head;
|
||||||
|
QLp *tail;
|
||||||
|
} QLock;
|
||||||
|
|
||||||
|
extern void qlock(QLock*);
|
||||||
|
extern void qunlock(QLock*);
|
||||||
|
extern int canqlock(QLock*);
|
||||||
|
extern void _qlockinit(ulong (*)(ulong, ulong)); /* called only by the thread library */
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct RWLock
|
||||||
|
{
|
||||||
|
Lock lock;
|
||||||
|
int readers; /* number of readers */
|
||||||
|
int writer; /* number of writers */
|
||||||
|
QLp *head; /* list of waiting processes */
|
||||||
|
QLp *tail;
|
||||||
|
} RWLock;
|
||||||
|
|
||||||
|
extern void rlock(RWLock*);
|
||||||
|
extern void runlock(RWLock*);
|
||||||
|
extern int canrlock(RWLock*);
|
||||||
|
extern void wlock(RWLock*);
|
||||||
|
extern void wunlock(RWLock*);
|
||||||
|
extern int canwlock(RWLock*);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct Rendez
|
||||||
|
{
|
||||||
|
QLock *l;
|
||||||
|
QLp *head;
|
||||||
|
QLp *tail;
|
||||||
|
} Rendez;
|
||||||
|
|
||||||
|
extern void rsleep(Rendez*); /* unlocks r->l, sleeps, locks r->l again */
|
||||||
|
extern int rwakeup(Rendez*);
|
||||||
|
extern int rwakeupall(Rendez*);
|
||||||
|
extern void** privalloc(void);
|
||||||
|
extern void privfree(void**);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* network dialing
|
||||||
|
*/
|
||||||
|
#define NETPATHLEN 40
|
||||||
|
extern int p9accept(int, char*);
|
||||||
|
extern int p9announce(char*, char*);
|
||||||
|
extern int p9dial(char*, char*, char*, int*);
|
||||||
|
extern void p9setnetmtpt(char*, int, char*);
|
||||||
|
extern int p9hangup(int);
|
||||||
|
extern int p9listen(char*, char*);
|
||||||
|
extern char* p9netmkaddr(char*, char*, char*);
|
||||||
|
extern int p9reject(int, char*, char*);
|
||||||
|
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define accept p9accept
|
||||||
|
#define announce p9announce
|
||||||
|
#define dial p9dial
|
||||||
|
#define setnetmtpt p9setnetmtpt
|
||||||
|
#define hangup p9hangup
|
||||||
|
#define listen p9listen
|
||||||
|
#define netmkaddr p9netmkaddr
|
||||||
|
#define reject p9reject
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* encryption
|
||||||
|
*/
|
||||||
|
extern int pushssl(int, char*, char*, char*, int*);
|
||||||
|
extern int pushtls(int, char*, char*, int, char*, char*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* network services
|
||||||
|
*/
|
||||||
|
typedef struct NetConnInfo NetConnInfo;
|
||||||
|
struct NetConnInfo
|
||||||
|
{
|
||||||
|
char *dir; /* connection directory */
|
||||||
|
char *root; /* network root */
|
||||||
|
char *spec; /* binding spec */
|
||||||
|
char *lsys; /* local system */
|
||||||
|
char *lserv; /* local service */
|
||||||
|
char *rsys; /* remote system */
|
||||||
|
char *rserv; /* remote service */
|
||||||
|
};
|
||||||
|
extern NetConnInfo* getnetconninfo(char*, int);
|
||||||
|
extern void freenetconninfo(NetConnInfo*);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* system calls
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define STATMAX 65535U /* max length of machine-independent stat structure */
|
||||||
|
#define DIRMAX (sizeof(Dir)+STATMAX) /* max length of Dir structure */
|
||||||
|
#define ERRMAX 128 /* max length of error string */
|
||||||
|
|
||||||
|
#define MORDER 0x0003 /* mask for bits defining order of mounting */
|
||||||
|
#define MREPL 0x0000 /* mount replaces object */
|
||||||
|
#define MBEFORE 0x0001 /* mount goes before others in union directory */
|
||||||
|
#define MAFTER 0x0002 /* mount goes after others in union directory */
|
||||||
|
#define MCREATE 0x0004 /* permit creation in mounted directory */
|
||||||
|
#define MCACHE 0x0010 /* cache some data */
|
||||||
|
#define MMASK 0x0017 /* all bits on */
|
||||||
|
|
||||||
|
#define OREAD 0 /* open for read */
|
||||||
|
#define OWRITE 1 /* write */
|
||||||
|
#define ORDWR 2 /* read and write */
|
||||||
|
#define OEXEC 3 /* execute, == read but check execute permission */
|
||||||
|
#define OTRUNC 16 /* or'ed in (except for exec), truncate file first */
|
||||||
|
#define OCEXEC 32 /* or'ed in, close on exec */
|
||||||
|
#define ORCLOSE 64 /* or'ed in, remove on close */
|
||||||
|
#define OEXCL 0x1000 /* or'ed in, exclusive use (create only) */
|
||||||
|
|
||||||
|
#define AEXIST 0 /* accessible: exists */
|
||||||
|
#define AEXEC 1 /* execute access */
|
||||||
|
#define AWRITE 2 /* write access */
|
||||||
|
#define AREAD 4 /* read access */
|
||||||
|
|
||||||
|
/* Segattch */
|
||||||
|
#define SG_RONLY 0040 /* read only */
|
||||||
|
#define SG_CEXEC 0100 /* detach on exec */
|
||||||
|
|
||||||
|
#define NCONT 0 /* continue after note */
|
||||||
|
#define NDFLT 1 /* terminate after note */
|
||||||
|
#define NSAVE 2 /* clear note but hold state */
|
||||||
|
#define NRSTR 3 /* restore saved state */
|
||||||
|
|
||||||
|
/* bits in Qid.type */
|
||||||
|
#define QTDIR 0x80 /* type bit for directories */
|
||||||
|
#define QTAPPEND 0x40 /* type bit for append only files */
|
||||||
|
#define QTEXCL 0x20 /* type bit for exclusive use files */
|
||||||
|
#define QTMOUNT 0x10 /* type bit for mounted channel */
|
||||||
|
#define QTAUTH 0x08 /* type bit for authentication file */
|
||||||
|
#define QTFILE 0x00 /* plain file */
|
||||||
|
|
||||||
|
/* bits in Dir.mode */
|
||||||
|
#define DMDIR 0x80000000 /* mode bit for directories */
|
||||||
|
#define DMAPPEND 0x40000000 /* mode bit for append only files */
|
||||||
|
#define DMEXCL 0x20000000 /* mode bit for exclusive use files */
|
||||||
|
#define DMMOUNT 0x10000000 /* mode bit for mounted channel */
|
||||||
|
#define DMAUTH 0x08000000 /* mode bit for authentication file */
|
||||||
|
#define DMREAD 0x4 /* mode bit for read permission */
|
||||||
|
#define DMWRITE 0x2 /* mode bit for write permission */
|
||||||
|
#define DMEXEC 0x1 /* mode bit for execute permission */
|
||||||
|
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
#undef RFFDG
|
||||||
|
#undef RFNOTEG
|
||||||
|
#undef RFPROC
|
||||||
|
#undef RFMEM
|
||||||
|
#undef RFNOWAIT
|
||||||
|
#undef RFCFDG
|
||||||
|
#undef RFNAMEG
|
||||||
|
#undef RFENVG
|
||||||
|
#undef RFCENVG
|
||||||
|
#undef RFCFDG
|
||||||
|
#undef RFCNAMEG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
RFNAMEG = (1<<0),
|
||||||
|
RFENVG = (1<<1),
|
||||||
|
RFFDG = (1<<2),
|
||||||
|
RFNOTEG = (1<<3),
|
||||||
|
RFPROC = (1<<4),
|
||||||
|
RFMEM = (1<<5),
|
||||||
|
RFNOWAIT = (1<<6),
|
||||||
|
RFCNAMEG = (1<<10),
|
||||||
|
RFCENVG = (1<<11),
|
||||||
|
RFCFDG = (1<<12),
|
||||||
|
/* RFREND = (1<<13), */
|
||||||
|
/* RFNOMNT = (1<<14) */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int ffork(int, void(*)(void*), void*);
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct Qid
|
||||||
|
{
|
||||||
|
uvlong path;
|
||||||
|
ulong vers;
|
||||||
|
uchar type;
|
||||||
|
} Qid;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct Dir {
|
||||||
|
/* system-modified data */
|
||||||
|
ushort type; /* server type */
|
||||||
|
uint dev; /* server subtype */
|
||||||
|
/* file data */
|
||||||
|
Qid qid; /* unique id from server */
|
||||||
|
ulong mode; /* permissions */
|
||||||
|
ulong atime; /* last read time */
|
||||||
|
ulong mtime; /* last write time */
|
||||||
|
vlong length; /* file length */
|
||||||
|
char *name; /* last element of path */
|
||||||
|
char *uid; /* owner name */
|
||||||
|
char *gid; /* group name */
|
||||||
|
char *muid; /* last modifier name */
|
||||||
|
} Dir;
|
||||||
|
|
||||||
|
/* keep /sys/src/ape/lib/ap/plan9/sys9.h in sync with this -rsc */
|
||||||
|
typedef
|
||||||
|
struct Waitmsg
|
||||||
|
{
|
||||||
|
int pid; /* of loved one */
|
||||||
|
ulong time[3]; /* of loved one & descendants */
|
||||||
|
char *msg;
|
||||||
|
} Waitmsg;
|
||||||
|
|
||||||
|
typedef
|
||||||
|
struct IOchunk
|
||||||
|
{
|
||||||
|
void *addr;
|
||||||
|
ulong len;
|
||||||
|
} IOchunk;
|
||||||
|
|
||||||
|
extern void _exits(char*);
|
||||||
|
|
||||||
|
extern void abort(void);
|
||||||
|
extern int p9access(char*, int);
|
||||||
|
extern long p9alarm(ulong);
|
||||||
|
extern int await(char*, int);
|
||||||
|
extern int awaitnohang(char*, int);
|
||||||
|
/* extern int bind(char*, char*, int); give up */
|
||||||
|
/* extern int brk(void*); <unistd.h> */
|
||||||
|
extern int p9chdir(char*);
|
||||||
|
extern int close(int);
|
||||||
|
extern int p9create(char*, int, ulong);
|
||||||
|
extern int p9dup(int, int);
|
||||||
|
extern int errstr(char*, uint);
|
||||||
|
extern int p9exec(char*, char*[]);
|
||||||
|
/* extern int execl(char*, ...); <unistd.h> */
|
||||||
|
/* extern int fork(void); <unistd.h> */
|
||||||
|
extern int p9rfork(int);
|
||||||
|
/* not implemented
|
||||||
|
extern int fauth(int, char*);
|
||||||
|
extern int fstat(int, uchar*, int);
|
||||||
|
extern int fwstat(int, uchar*, int);
|
||||||
|
extern int fversion(int, int, char*, int);
|
||||||
|
extern int mount(int, int, char*, int, char*);
|
||||||
|
extern int unmount(char*, char*);
|
||||||
|
*/
|
||||||
|
extern int noted(int);
|
||||||
|
extern int notify(void(*)(void*, char*));
|
||||||
|
extern int p9open(char*, int);
|
||||||
|
extern int fd2path(int, char*, int);
|
||||||
|
extern int p9pipe(int*);
|
||||||
|
/*
|
||||||
|
* use defs from <unistd.h>
|
||||||
|
extern long pread(int, void*, long, vlong);
|
||||||
|
extern long preadv(int, IOchunk*, int, vlong);
|
||||||
|
extern long pwrite(int, void*, long, vlong);
|
||||||
|
extern long pwritev(int, IOchunk*, int, vlong);
|
||||||
|
extern long read(int, void*, long);
|
||||||
|
*/
|
||||||
|
extern long readn(int, void*, long);
|
||||||
|
/* extern long readv(int, IOchunk*, int); <unistd.h> */
|
||||||
|
extern int remove(const char*);
|
||||||
|
/* extern void* sbrk(ulong); <unistd.h> */
|
||||||
|
/* extern long oseek(int, long, int); */
|
||||||
|
extern vlong p9seek(int, vlong, int);
|
||||||
|
/* give up
|
||||||
|
extern long segattach(int, char*, void*, ulong);
|
||||||
|
extern int segbrk(void*, void*);
|
||||||
|
extern int segdetach(void*);
|
||||||
|
extern int segflush(void*, ulong);
|
||||||
|
extern int segfree(void*, ulong);
|
||||||
|
*/
|
||||||
|
extern int p9sleep(long);
|
||||||
|
/* extern int stat(char*, uchar*, int); give up */
|
||||||
|
extern Waitmsg* p9wait(void);
|
||||||
|
extern Waitmsg* waitnohang(void);
|
||||||
|
extern int p9waitpid(void);
|
||||||
|
/* <unistd.h>
|
||||||
|
extern long write(int, void*, long);
|
||||||
|
extern long writev(int, IOchunk*, int);
|
||||||
|
*/
|
||||||
|
/* extern int wstat(char*, uchar*, int); give up */
|
||||||
|
extern ulong rendezvous(ulong, ulong);
|
||||||
|
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define alarm p9alarm
|
||||||
|
#define dup p9dup
|
||||||
|
#define exec p9exec
|
||||||
|
#define seek p9seek
|
||||||
|
#define sleep p9sleep
|
||||||
|
#define wait p9wait
|
||||||
|
#define waitpid p9waitpid
|
||||||
|
#define rfork p9rfork
|
||||||
|
#define access p9access
|
||||||
|
#define create p9create
|
||||||
|
#define open p9open
|
||||||
|
#define pipe p9pipe
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern Dir* dirstat(char*);
|
||||||
|
extern Dir* dirfstat(int);
|
||||||
|
extern int dirwstat(char*, Dir*);
|
||||||
|
extern int dirfwstat(int, Dir*);
|
||||||
|
extern long dirread(int, Dir**);
|
||||||
|
extern void nulldir(Dir*);
|
||||||
|
extern long dirreadall(int, Dir**);
|
||||||
|
/* extern int getpid(void); <unistd.h> */
|
||||||
|
/* extern int getppid(void); */
|
||||||
|
extern void rerrstr(char*, uint);
|
||||||
|
extern char* sysname(void);
|
||||||
|
extern void werrstr(char*, ...);
|
||||||
|
extern char* getns(void);
|
||||||
|
extern char* get9root(void);
|
||||||
|
extern char* unsharp(char*);
|
||||||
|
extern int sendfd(int, int);
|
||||||
|
extern int recvfd(int);
|
||||||
|
extern int post9pservice(int, char*);
|
||||||
|
|
||||||
|
/* external names that we don't want to step on */
|
||||||
|
#ifndef NOPLAN9DEFINES
|
||||||
|
#define main p9main
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* compiler directives on plan 9 */
|
||||||
|
#define USED(x) if(x){}else{}
|
||||||
|
#define SET(x) ((x)=0)
|
||||||
|
|
||||||
|
/* command line */
|
||||||
|
extern char *argv0;
|
||||||
|
extern void __fixargv0(void);
|
||||||
|
#define ARGBEGIN for((argv0?0:(argv0=(__fixargv0(),*argv))),argv++,argc--;\
|
||||||
|
argv[0] && argv[0][0]=='-' && argv[0][1];\
|
||||||
|
argc--, argv++) {\
|
||||||
|
char *_args, *_argt;\
|
||||||
|
Rune _argc;\
|
||||||
|
_args = &argv[0][1];\
|
||||||
|
if(_args[0]=='-' && _args[1]==0){\
|
||||||
|
argc--; argv++; break;\
|
||||||
|
}\
|
||||||
|
_argc = 0;\
|
||||||
|
while(*_args && (_args += chartorune(&_argc, _args)))\
|
||||||
|
switch(_argc)
|
||||||
|
#define ARGEND SET(_argt);USED(_argt);USED(_argc);USED(_args);}USED(argv);USED(argc);
|
||||||
|
#define ARGF() (_argt=_args, _args="",\
|
||||||
|
(*_argt? _argt: argv[1]? (argc--, *++argv): 0))
|
||||||
|
#define EARGF(x) (_argt=_args, _args="",\
|
||||||
|
(*_argt? _argt: argv[1]? (argc--, *++argv): ((x), abort(), (char*)0)))
|
||||||
|
|
||||||
|
#define ARGC() _argc
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif /* _LIB9_H_ */
|
||||||
|
|
93
include/u.h
93
include/u.h
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef _U_H_
|
||||||
|
#define _U_H_ 1
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _BSD_SOURCE 1
|
||||||
|
#define _SVID_SOURCE 1
|
||||||
|
#define _XOPEN_SOURCE 1000
|
||||||
|
#define _XOPEN_SOURCE_EXTENDED 1
|
||||||
|
#define _LARGEFILE64_SOURCE 1
|
||||||
|
#define _FILE_OFFSET_BITS 64
|
||||||
|
#define __EXTENSIONS__ 1 /* SunOS */
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <utf.h>
|
||||||
|
#include <fmt.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OS-specific crap
|
||||||
|
*/
|
||||||
|
#define _NEEDUCHAR 1
|
||||||
|
#define _NEEDUSHORT 1
|
||||||
|
#define _NEEDUINT 1
|
||||||
|
#define _NEEDULONG 1
|
||||||
|
|
||||||
|
typedef long p9jmp_buf[sizeof(sigjmp_buf)/sizeof(long)];
|
||||||
|
|
||||||
|
#if defined(__linux__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# if defined(__USE_MISC)
|
||||||
|
# undef _NEEDUSHORT
|
||||||
|
# undef _NEEDUINT
|
||||||
|
# undef _NEEDULONG
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(__sun__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# undef _NEEDUSHORT
|
||||||
|
# undef _NEEDUINT
|
||||||
|
# undef _NEEDULONG
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# if !defined(_POSIX_SOURCE)
|
||||||
|
# undef _NEEDUSHORT
|
||||||
|
# undef _NEEDUINT
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
# include <sys/types.h>
|
||||||
|
# undef _NEEDUSHORT
|
||||||
|
# undef _NEEDUINT
|
||||||
|
# define _NEEDLL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef signed char schar;
|
||||||
|
typedef unsigned int u32int;
|
||||||
|
#ifdef _NEEDUCHAR
|
||||||
|
typedef unsigned char uchar;
|
||||||
|
#endif
|
||||||
|
#ifdef _NEEDUSHORT
|
||||||
|
typedef unsigned short ushort;
|
||||||
|
#endif
|
||||||
|
#ifdef _NEEDUINT
|
||||||
|
typedef unsigned int uint;
|
||||||
|
#endif
|
||||||
|
#ifdef _NEEDULONG
|
||||||
|
typedef unsigned long ulong;
|
||||||
|
#endif
|
||||||
|
typedef unsigned long long uvlong;
|
||||||
|
typedef long long vlong;
|
||||||
|
typedef uvlong u64int;
|
||||||
|
typedef uchar u8int;
|
||||||
|
typedef ushort u16int;
|
||||||
|
|
||||||
|
#undef _NEEDUCHAR
|
||||||
|
#undef _NEEDUSHORT
|
||||||
|
#undef _NEEDUINT
|
||||||
|
#undef _NEEDULONG
|
||||||
|
|
||||||
|
#if defined(__cplusplus)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
|
@ -1150,7 +1150,7 @@ rewritehdr(Fcall *f, uchar *pkt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _LIB9_H_
|
#ifdef _LIBC_H_
|
||||||
/* unix select-based polling */
|
/* unix select-based polling */
|
||||||
struct Ioproc
|
struct Ioproc
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,15 +1,24 @@
|
||||||
#include "9term.h"
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
#define fatal sysfatal
|
#include <ctype.h>
|
||||||
|
#include <draw.h>
|
||||||
|
#include <thread.h>
|
||||||
|
#include <mouse.h>
|
||||||
|
#include <cursor.h>
|
||||||
|
#include <keyboard.h>
|
||||||
|
#include <frame.h>
|
||||||
|
#include <plumb.h>
|
||||||
|
#include <complete.h>
|
||||||
|
#include "term.h"
|
||||||
|
|
||||||
typedef struct Text Text;
|
typedef struct Text Text;
|
||||||
typedef struct Readbuf Readbuf;
|
typedef struct Readbuf Readbuf;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
/* these are chosen to use malloc()'s properties well */
|
|
||||||
HiWater = 640000, /* max size of history */
|
HiWater = 640000, /* max size of history */
|
||||||
LoWater = 330000, /* min size of history after max'ed */
|
LoWater = 400000, /* min size of history after max'ed */
|
||||||
|
MinWater = 20000,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* various geometric paramters */
|
/* various geometric paramters */
|
||||||
|
@ -30,21 +39,22 @@ enum
|
||||||
Scroll,
|
Scroll,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#define SCROLLKEY Kdown
|
|
||||||
#define ESC 0x1B
|
#define ESC 0x1B
|
||||||
#define CUT 0x18 /* ctrl-x */
|
#define CUT 0x18 /* ctrl-x */
|
||||||
#define COPY 0x03 /* crtl-c */
|
#define COPY 0x03 /* crtl-c */
|
||||||
#define PASTE 0x16 /* crtl-v */
|
#define PASTE 0x16 /* crtl-v */
|
||||||
#define BACKSCROLLKEY Kup
|
|
||||||
|
|
||||||
#define READBUFSIZE 8192
|
#define READBUFSIZE 8192
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
|
||||||
|
|
||||||
struct Text
|
struct Text
|
||||||
{
|
{
|
||||||
Frame *f; /* frame ofr terminal */
|
Frame *f; /* frame ofr terminal */
|
||||||
Mouse m;
|
Mouse m;
|
||||||
uint nr; /* num of runes in term */
|
uint nr; /* num of runes in term */
|
||||||
|
uint maxr; /* max num of runes in r */
|
||||||
Rune *r; /* runes for term */
|
Rune *r; /* runes for term */
|
||||||
uint nraw; /* num of runes in raw buffer */
|
uint nraw; /* num of runes in raw buffer */
|
||||||
Rune *raw; /* raw buffer */
|
Rune *raw; /* raw buffer */
|
||||||
|
@ -72,7 +82,6 @@ void fill(void);
|
||||||
void tcheck(void);
|
void tcheck(void);
|
||||||
void updatesel(void);
|
void updatesel(void);
|
||||||
void doreshape(void);
|
void doreshape(void);
|
||||||
void rcstart(int fd[2], int, char**);
|
|
||||||
void runewrite(Rune*, int);
|
void runewrite(Rune*, int);
|
||||||
void consread(void);
|
void consread(void);
|
||||||
void conswrite(char*, int);
|
void conswrite(char*, int);
|
||||||
|
@ -99,11 +108,10 @@ void scrdraw(void);
|
||||||
void scroll(int);
|
void scroll(int);
|
||||||
void hostproc(void *arg);
|
void hostproc(void *arg);
|
||||||
void hoststart(void);
|
void hoststart(void);
|
||||||
int getchildwd(int, char*, int);
|
|
||||||
void plumbstart(void);
|
void plumbstart(void);
|
||||||
void plumb(uint, uint);
|
void plumb(uint, uint);
|
||||||
void plumbclick(uint*, uint*);
|
void plumbclick(uint*, uint*);
|
||||||
int getpts(int fd[], char *slave);
|
uint insert(Rune*, int, uint, int);
|
||||||
|
|
||||||
#define runemalloc(n) malloc((n)*sizeof(Rune))
|
#define runemalloc(n) malloc((n)*sizeof(Rune))
|
||||||
#define runerealloc(a, n) realloc(a, (n)*sizeof(Rune))
|
#define runerealloc(a, n) realloc(a, (n)*sizeof(Rune))
|
||||||
|
@ -115,7 +123,7 @@ int rawon; /* raw mode */
|
||||||
int scrolling; /* window scrolls */
|
int scrolling; /* window scrolls */
|
||||||
int clickmsec; /* time of last click */
|
int clickmsec; /* time of last click */
|
||||||
uint clickq0; /* point of last click */
|
uint clickq0; /* point of last click */
|
||||||
int rcfd[2];
|
int rcfd;
|
||||||
int rcpid;
|
int rcpid;
|
||||||
int maxtab;
|
int maxtab;
|
||||||
int use9wm;
|
int use9wm;
|
||||||
|
@ -211,7 +219,7 @@ threadmain(int argc, char *argv[])
|
||||||
|
|
||||||
mc = initmouse(nil, screen);
|
mc = initmouse(nil, screen);
|
||||||
kc = initkeyboard(nil);
|
kc = initkeyboard(nil);
|
||||||
rcstart(rcfd, argc, argv);
|
rcpid = rcstart(argc, argv, &rcfd);
|
||||||
hoststart();
|
hoststart();
|
||||||
plumbstart();
|
plumbstart();
|
||||||
|
|
||||||
|
@ -265,8 +273,9 @@ hostproc(void *arg)
|
||||||
|
|
||||||
i = 0;
|
i = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
|
/* Let typing have a go -- maybe there's a rubout waiting. */
|
||||||
i = 1-i; /* toggle */
|
i = 1-i; /* toggle */
|
||||||
n = threadread(rcfd[0], rcbuf[i].data, sizeof rcbuf[i].data);
|
n = threadread(rcfd, rcbuf[i].data, sizeof rcbuf[i].data);
|
||||||
if(n <= 0){
|
if(n <= 0){
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
fprint(2, "9term: host read error: %r\n");
|
fprint(2, "9term: host read error: %r\n");
|
||||||
|
@ -308,7 +317,7 @@ loop(void)
|
||||||
a[2].op = CHANNOP;;
|
a[2].op = CHANNOP;;
|
||||||
switch(alt(a)) {
|
switch(alt(a)) {
|
||||||
default:
|
default:
|
||||||
fatal("impossible");
|
sysfatal("impossible");
|
||||||
case 0:
|
case 0:
|
||||||
t.m = mc->m;
|
t.m = mc->m;
|
||||||
mouse();
|
mouse();
|
||||||
|
@ -330,23 +339,23 @@ void
|
||||||
doreshape(void)
|
doreshape(void)
|
||||||
{
|
{
|
||||||
if(getwindow(display, Refnone) < 0)
|
if(getwindow(display, Refnone) < 0)
|
||||||
fatal("can't reattach to window");
|
sysfatal("can't reattach to window");
|
||||||
draw(screen, screen->r, cols[BACK], nil, ZP);
|
draw(screen, screen->r, cols[BACK], nil, ZP);
|
||||||
geom();
|
geom();
|
||||||
scrdraw();
|
scrdraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct winsize ows;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
geom(void)
|
geom(void)
|
||||||
{
|
{
|
||||||
struct winsize ws;
|
|
||||||
Point p;
|
Point p;
|
||||||
Rectangle r;
|
Rectangle r;
|
||||||
|
|
||||||
r = screen->r;
|
r = screen->r;
|
||||||
scrollr = screen->r;
|
r.min.y++;
|
||||||
|
r.max.y--;
|
||||||
|
|
||||||
|
scrollr = r;
|
||||||
scrollr.max.x = r.min.x+Scrollwid;
|
scrollr.max.x = r.min.x+Scrollwid;
|
||||||
lastsr = Rect(0,0,0,0);
|
lastsr = Rect(0,0,0,0);
|
||||||
|
|
||||||
|
@ -362,13 +371,7 @@ geom(void)
|
||||||
if(p.x == 0 || p.y == 0)
|
if(p.x == 0 || p.y == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ws.ws_row = Dy(r)/p.y;
|
updatewinsize(Dy(r)/p.y, Dx(r)/p.x, Dx(r), Dy(r));
|
||||||
ws.ws_col = Dx(r)/p.x;
|
|
||||||
ws.ws_xpixel = Dx(r);
|
|
||||||
ws.ws_ypixel = Dy(r);
|
|
||||||
if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col)
|
|
||||||
if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0)
|
|
||||||
fprint(2, "ioctl: %r\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -585,7 +588,10 @@ domenu2(int but)
|
||||||
show(t.q0);
|
show(t.q0);
|
||||||
break;
|
break;
|
||||||
case Send:
|
case Send:
|
||||||
snarf();
|
if(t.q0 != t.q1)
|
||||||
|
snarf();
|
||||||
|
else
|
||||||
|
snarfupdate();
|
||||||
t.q0 = t.q1 = t.nr;
|
t.q0 = t.q1 = t.nr;
|
||||||
updatesel();
|
updatesel();
|
||||||
paste(t.snarf, t.nsnarf, 1);
|
paste(t.snarf, t.nsnarf, 1);
|
||||||
|
@ -605,37 +611,182 @@ domenu2(int but)
|
||||||
plumb(t.q0, t.q1);
|
plumb(t.q0, t.q1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fatal("bad menu item");
|
sysfatal("bad menu item");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
windfilewidth(uint q0, int oneelement)
|
||||||
|
{
|
||||||
|
uint q;
|
||||||
|
Rune r;
|
||||||
|
|
||||||
|
q = q0;
|
||||||
|
while(q > 0){
|
||||||
|
r = t.r[q-1];
|
||||||
|
if(r<=' ')
|
||||||
|
break;
|
||||||
|
if(oneelement && r=='/')
|
||||||
|
break;
|
||||||
|
--q;
|
||||||
|
}
|
||||||
|
return q0-q;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
showcandidates(Completion *c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Fmt f;
|
||||||
|
Rune *rp;
|
||||||
|
uint nr, qline, q0;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
runefmtstrinit(&f);
|
||||||
|
if (c->nmatch == 0)
|
||||||
|
s = "[no matches in ";
|
||||||
|
else
|
||||||
|
s = "[";
|
||||||
|
if(c->nfile > 32)
|
||||||
|
fmtprint(&f, "%s%d files]\n", s, c->nfile);
|
||||||
|
else{
|
||||||
|
fmtprint(&f, "%s", s);
|
||||||
|
for(i=0; i<c->nfile; i++){
|
||||||
|
if(i > 0)
|
||||||
|
fmtprint(&f, " ");
|
||||||
|
fmtprint(&f, "%s", c->filename[i]);
|
||||||
|
}
|
||||||
|
fmtprint(&f, "]\n");
|
||||||
|
}
|
||||||
|
/* place text at beginning of line before host point */
|
||||||
|
qline = t.qh;
|
||||||
|
while(qline>0 && t.r[qline-1] != '\n')
|
||||||
|
qline--;
|
||||||
|
|
||||||
|
rp = runefmtstrflush(&f);
|
||||||
|
nr = runestrlen(rp);
|
||||||
|
|
||||||
|
q0 = t.q0;
|
||||||
|
q0 += insert(rp, nr, qline, 0) - qline;
|
||||||
|
free(rp);
|
||||||
|
t.q0 = q0+nr;
|
||||||
|
t.q1 = q0+nr;
|
||||||
|
updatesel();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rune*
|
||||||
|
namecomplete(void)
|
||||||
|
{
|
||||||
|
int nstr, npath;
|
||||||
|
Rune *rp, *path, *str;
|
||||||
|
Completion *c;
|
||||||
|
char *s, *dir, *root;
|
||||||
|
|
||||||
|
/* control-f: filename completion; works back to white space or / */
|
||||||
|
if(t.q0<t.nr && t.r[t.q0]>' ') /* must be at end of word */
|
||||||
|
return nil;
|
||||||
|
nstr = windfilewidth(t.q0, TRUE);
|
||||||
|
str = runemalloc(nstr);
|
||||||
|
runemove(str, t.r+(t.q0-nstr), nstr);
|
||||||
|
npath = windfilewidth(t.q0-nstr, FALSE);
|
||||||
|
path = runemalloc(npath);
|
||||||
|
runemove(path, t.r+(t.q0-nstr-npath), npath);
|
||||||
|
rp = nil;
|
||||||
|
|
||||||
|
/* is path rooted? if not, we need to make it relative to window path */
|
||||||
|
if(npath>0 && path[0]=='/'){
|
||||||
|
dir = malloc(UTFmax*npath+1);
|
||||||
|
sprint(dir, "%.*S", npath, path);
|
||||||
|
}else{
|
||||||
|
if(strcmp(wdir, "") == 0)
|
||||||
|
root = ".";
|
||||||
|
else
|
||||||
|
root = wdir;
|
||||||
|
dir = malloc(strlen(root)+1+UTFmax*npath+1);
|
||||||
|
sprint(dir, "%s/%.*S", root, npath, path);
|
||||||
|
}
|
||||||
|
dir = cleanname(dir);
|
||||||
|
|
||||||
|
s = smprint("%.*S", nstr, str);
|
||||||
|
c = complete(dir, s);
|
||||||
|
free(s);
|
||||||
|
if(c == nil)
|
||||||
|
goto Return;
|
||||||
|
|
||||||
|
if(!c->advance)
|
||||||
|
showcandidates(c);
|
||||||
|
|
||||||
|
if(c->advance)
|
||||||
|
rp = runesmprint("%s", c->string);
|
||||||
|
|
||||||
|
Return:
|
||||||
|
freecompletion(c);
|
||||||
|
free(dir);
|
||||||
|
free(path);
|
||||||
|
free(str);
|
||||||
|
return rp;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
key(Rune r)
|
key(Rune r)
|
||||||
{
|
{
|
||||||
uint sig;
|
Rune *rp;
|
||||||
|
int nr;
|
||||||
|
|
||||||
if(r == 0)
|
if(r == 0)
|
||||||
return;
|
return;
|
||||||
if(r==SCROLLKEY){ /* scroll key */
|
switch(r){
|
||||||
|
case Kpgup:
|
||||||
|
setorigin(backnl(t.org, t.f->maxlines*2/3), 1);
|
||||||
|
return;
|
||||||
|
case Kpgdown:
|
||||||
setorigin(line2q(t.f->maxlines*2/3), 1);
|
setorigin(line2q(t.f->maxlines*2/3), 1);
|
||||||
if(t.qh<=t.org+t.f->nchars)
|
if(t.qh<=t.org+t.f->nchars)
|
||||||
consread();
|
consread();
|
||||||
return;
|
return;
|
||||||
}else if(r == BACKSCROLLKEY){
|
case Kup:
|
||||||
setorigin(backnl(t.org, t.f->maxlines*2/3), 1);
|
setorigin(backnl(t.org, t.f->maxlines/3), 1);
|
||||||
return;
|
return;
|
||||||
}else if(r == CUT){
|
case Kdown:
|
||||||
|
setorigin(line2q(t.f->maxlines/3), 1);
|
||||||
|
if(t.qh<=t.org+t.f->nchars)
|
||||||
|
consread();
|
||||||
|
return;
|
||||||
|
case Kleft:
|
||||||
|
if(t.q0 > 0){
|
||||||
|
t.q0--;
|
||||||
|
t.q1 = t.q0;
|
||||||
|
updatesel();
|
||||||
|
show(t.q0);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Kright:
|
||||||
|
if(t.q1 < t.nr){
|
||||||
|
t.q1++;
|
||||||
|
t.q0 = t.q1;
|
||||||
|
updatesel();
|
||||||
|
show(t.q1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case Khome:
|
||||||
|
show(0);
|
||||||
|
return;
|
||||||
|
case Kend:
|
||||||
|
case 0x05:
|
||||||
|
show(t.nr);
|
||||||
|
return;
|
||||||
|
case CUT:
|
||||||
snarf();
|
snarf();
|
||||||
cut();
|
cut();
|
||||||
if(scrolling)
|
if(scrolling)
|
||||||
show(t.q0);
|
show(t.q0);
|
||||||
return;
|
return;
|
||||||
}else if(r == COPY){
|
case COPY:
|
||||||
snarf();
|
snarf();
|
||||||
if(scrolling)
|
if(scrolling)
|
||||||
show(t.q0);
|
show(t.q0);
|
||||||
return;
|
return;
|
||||||
}else if(r == PASTE){
|
case PASTE:
|
||||||
snarfupdate();
|
snarfupdate();
|
||||||
paste(t.snarf, t.nsnarf, 0);
|
paste(t.snarf, t.nsnarf, 0);
|
||||||
if(scrolling)
|
if(scrolling)
|
||||||
|
@ -661,19 +812,21 @@ key(Rune r)
|
||||||
snarf();
|
snarf();
|
||||||
|
|
||||||
switch(r) {
|
switch(r) {
|
||||||
|
case 0x03: /* ^C: send interrupt */
|
||||||
case 0x7F: /* DEL: send interrupt */
|
case 0x7F: /* DEL: send interrupt */
|
||||||
t.qh = t.q0 = t.q1 = t.nr;
|
t.qh = t.q0 = t.q1 = t.nr;
|
||||||
show(t.q0);
|
show(t.q0);
|
||||||
goto Default;
|
write(rcfd, "\x7F", 1);
|
||||||
fprint(2, "send interrupt to %d group\n", rcpid);
|
|
||||||
#ifdef TIOCSIG
|
|
||||||
sig = 2; /* SIGINT */
|
|
||||||
if(ioctl(rcfd[0], TIOCSIG, &sig) < 0)
|
|
||||||
fprint(2, "sending interrupt: %r\n");
|
|
||||||
#else
|
|
||||||
postnote(PNGROUP, rcpid, "interrupt");
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
case 0x06: /* ^F: file name completion */
|
||||||
|
case Kins: /* Insert: file name completion */
|
||||||
|
rp = namecomplete();
|
||||||
|
if(rp == nil)
|
||||||
|
return;
|
||||||
|
nr = runestrlen(rp);
|
||||||
|
paste(rp, nr, 1);
|
||||||
|
free(rp);
|
||||||
|
return;
|
||||||
case 0x08: /* ^H: erase character */
|
case 0x08: /* ^H: erase character */
|
||||||
case 0x15: /* ^U: erase line */
|
case 0x15: /* ^U: erase line */
|
||||||
case 0x17: /* ^W: erase word */
|
case 0x17: /* ^W: erase word */
|
||||||
|
@ -682,7 +835,6 @@ fprint(2, "send interrupt to %d group\n", rcpid);
|
||||||
cut();
|
cut();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
Default:
|
|
||||||
paste(&r, 1, 1);
|
paste(&r, 1, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -773,7 +925,7 @@ consread(void)
|
||||||
}
|
}
|
||||||
/* take out control-d when not doing a zero length write */
|
/* take out control-d when not doing a zero length write */
|
||||||
n = p-buf;
|
n = p-buf;
|
||||||
if(write(rcfd[1], buf, n) < 0)
|
if(write(rcfd, buf, n) < 0)
|
||||||
exits(0);
|
exits(0);
|
||||||
/* mallocstats(); */
|
/* mallocstats(); */
|
||||||
}
|
}
|
||||||
|
@ -833,7 +985,6 @@ conswrite(char *p, int n)
|
||||||
void
|
void
|
||||||
runewrite(Rune *r, int n)
|
runewrite(Rune *r, int n)
|
||||||
{
|
{
|
||||||
uint m;
|
|
||||||
int i;
|
int i;
|
||||||
uint initial;
|
uint initial;
|
||||||
uint q0, q1;
|
uint q0, q1;
|
||||||
|
@ -896,37 +1047,7 @@ runewrite(Rune *r, int n)
|
||||||
updatesel();
|
updatesel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t.nr>HiWater && t.qh>=t.org){
|
insert(r, n, t.qh, 1);
|
||||||
m = HiWater-LoWater;
|
|
||||||
if(m > t.org);
|
|
||||||
m = t.org;
|
|
||||||
t.org -= m;
|
|
||||||
t.qh -= m;
|
|
||||||
if(t.q0 > m)
|
|
||||||
t.q0 -= m;
|
|
||||||
else
|
|
||||||
t.q0 = 0;
|
|
||||||
if(t.q1 > m)
|
|
||||||
t.q1 -= m;
|
|
||||||
else
|
|
||||||
t.q1 = 0;
|
|
||||||
t.nr -= m;
|
|
||||||
runemove(t.r, t.r+m, t.nr);
|
|
||||||
}
|
|
||||||
t.r = runerealloc(t.r, t.nr+n);
|
|
||||||
runemove(t.r+t.qh+n, t.r+t.qh, t.nr-t.qh);
|
|
||||||
runemove(t.r+t.qh, r, n);
|
|
||||||
t.nr += n;
|
|
||||||
if(t.qh < t.org)
|
|
||||||
t.org += n;
|
|
||||||
else if(t.qh <= t.f->nchars+t.org)
|
|
||||||
frinsert(t.f, r, r+n, t.qh-t.org);
|
|
||||||
if (t.qh <= t.q0)
|
|
||||||
t.q0 += n;
|
|
||||||
if (t.qh <= t.q1)
|
|
||||||
t.q1 += n;
|
|
||||||
t.qh += n;
|
|
||||||
updatesel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1009,12 +1130,83 @@ snarf(void)
|
||||||
putsnarf(sbuf);
|
putsnarf(sbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
min(uint x, uint y)
|
||||||
|
{
|
||||||
|
if(x < y)
|
||||||
|
return x;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
max(uint x, uint y)
|
||||||
|
{
|
||||||
|
if(x > y)
|
||||||
|
return x;
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint
|
||||||
|
insert(Rune *r, int n, uint q0, int hostwrite)
|
||||||
|
{
|
||||||
|
uint m;
|
||||||
|
|
||||||
|
if(n == 0)
|
||||||
|
return q0;
|
||||||
|
if(t.nr+n>HiWater && q0>=t.org && q0>=t.qh){
|
||||||
|
m = min(HiWater-LoWater, min(t.org, t.qh));
|
||||||
|
t.org -= m;
|
||||||
|
t.qh -= m;
|
||||||
|
if(t.q0 > m)
|
||||||
|
t.q0 -= m;
|
||||||
|
else
|
||||||
|
t.q0 = 0;
|
||||||
|
if(t.q1 > m)
|
||||||
|
t.q1 -= m;
|
||||||
|
else
|
||||||
|
t.q1 = 0;
|
||||||
|
t.nr -= m;
|
||||||
|
runemove(t.r, t.r+m, t.nr);
|
||||||
|
q0 -= m;
|
||||||
|
}
|
||||||
|
if(t.nr+n > t.maxr){
|
||||||
|
/*
|
||||||
|
* Minimize realloc breakage:
|
||||||
|
* Allocate at least MinWater
|
||||||
|
* Double allocation size each time
|
||||||
|
* But don't go much above HiWater
|
||||||
|
*/
|
||||||
|
m = max(min(2*(t.nr+n), HiWater), t.nr+n)+MinWater;
|
||||||
|
if(m > HiWater)
|
||||||
|
m = max(HiWater+MinWater, t.nr+n);
|
||||||
|
if(m > t.maxr){
|
||||||
|
t.r = runerealloc(t.r, m);
|
||||||
|
t.maxr = m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runemove(t.r+q0+n, t.r+q0, t.nr-q0);
|
||||||
|
runemove(t.r+q0, r, n);
|
||||||
|
t.nr += n;
|
||||||
|
/* if output touches, advance selection, not qh; works best for keyboard and output */
|
||||||
|
if(q0 <= t.q1)
|
||||||
|
t.q1 += n;
|
||||||
|
if(q0 <= t.q0)
|
||||||
|
t.q0 += n;
|
||||||
|
if(q0 < t.qh || (q0==t.qh && hostwrite))
|
||||||
|
t.qh += n;
|
||||||
|
else
|
||||||
|
consread();
|
||||||
|
if(q0 < t.org)
|
||||||
|
t.org += n;
|
||||||
|
else if(q0 <= t.org+t.f->nchars)
|
||||||
|
frinsert(t.f, r, r+n, q0-t.org);
|
||||||
|
return q0;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
paste(Rune *r, int n, int advance)
|
paste(Rune *r, int n, int advance)
|
||||||
{
|
{
|
||||||
Rune *rbuf;
|
Rune *rbuf;
|
||||||
uint m;
|
|
||||||
uint q0;
|
|
||||||
|
|
||||||
if(rawon && t.q0==t.nr){
|
if(rawon && t.q0==t.nr){
|
||||||
addraw(r, n);
|
addraw(r, n);
|
||||||
|
@ -1024,6 +1216,7 @@ paste(Rune *r, int n, int advance)
|
||||||
cut();
|
cut();
|
||||||
if(n == 0)
|
if(n == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* if this is a button2 execute then we might have been passed
|
* if this is a button2 execute then we might have been passed
|
||||||
* runes inside the buffer. must save them before realloc.
|
* runes inside the buffer. must save them before realloc.
|
||||||
|
@ -1035,36 +1228,7 @@ paste(Rune *r, int n, int advance)
|
||||||
r = rbuf;
|
r = rbuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(t.nr>HiWater && t.q0>=t.org && t.q0>=t.qh){
|
insert(r, n, t.q0, 0);
|
||||||
m = HiWater-LoWater;
|
|
||||||
if(m > t.org)
|
|
||||||
m = t.org;
|
|
||||||
if(m > t.qh);
|
|
||||||
m = t.qh;
|
|
||||||
t.org -= m;
|
|
||||||
t.qh -= m;
|
|
||||||
t.q0 -= m;
|
|
||||||
t.q1 -= m;
|
|
||||||
t.nr -= m;
|
|
||||||
runemove(t.r, t.r+m, t.nr);
|
|
||||||
}
|
|
||||||
|
|
||||||
t.r = runerealloc(t.r, t.nr+n);
|
|
||||||
q0 = t.q0;
|
|
||||||
runemove(t.r+q0+n, t.r+q0, t.nr-q0);
|
|
||||||
runemove(t.r+q0, r, n);
|
|
||||||
t.nr += n;
|
|
||||||
if(q0 < t.qh)
|
|
||||||
t.qh += n;
|
|
||||||
else
|
|
||||||
consread();
|
|
||||||
if(q0 < t.org)
|
|
||||||
t.org += n;
|
|
||||||
else if(q0 <= t.f->nchars+t.org)
|
|
||||||
frinsert(t.f, r, r+n, q0-t.org);
|
|
||||||
if(advance)
|
|
||||||
t.q0 += n;
|
|
||||||
t.q1 += n;
|
|
||||||
updatesel();
|
updatesel();
|
||||||
free(rbuf);
|
free(rbuf);
|
||||||
}
|
}
|
||||||
|
@ -1321,61 +1485,6 @@ clickmatch(int cl, int cr, int dir, uint *q)
|
||||||
return cl=='\n' && nest==1;
|
return cl=='\n' && nest==1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
rcstart(int fd[2], int argc, char **argv)
|
|
||||||
{
|
|
||||||
int pid;
|
|
||||||
char *xargv[3];
|
|
||||||
char slave[256];
|
|
||||||
int sfd;
|
|
||||||
|
|
||||||
if(argc == 0){
|
|
||||||
argc = 2;
|
|
||||||
argv = xargv;
|
|
||||||
argv[0] = getenv("SHELL");
|
|
||||||
if(argv[0] == 0)
|
|
||||||
argv[0] = "rc";
|
|
||||||
argv[1] = "-i";
|
|
||||||
argv[2] = 0;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* fd0 is slave (tty), fd1 is master (pty)
|
|
||||||
*/
|
|
||||||
fd[0] = fd[1] = -1;
|
|
||||||
if(getpts(fd, slave) < 0)
|
|
||||||
fprint(2, "getpts: %r\n");
|
|
||||||
|
|
||||||
switch(pid = fork()) {
|
|
||||||
case 0:
|
|
||||||
putenv("TERM", "9term");
|
|
||||||
close(fd[1]);
|
|
||||||
setsid();
|
|
||||||
// tcsetpgrp(0, pid);
|
|
||||||
sfd = open(slave, ORDWR);
|
|
||||||
if(sfd < 0)
|
|
||||||
fprint(2, "open %s: %r\n", slave);
|
|
||||||
if(ioctl(sfd, TIOCSCTTY, 0) < 0)
|
|
||||||
fprint(2, "ioctl TIOCSCTTY: %r\n");
|
|
||||||
// ioctl(sfd, I_PUSH, "ptem");
|
|
||||||
// ioctl(sfd, I_PUSH, "ldterm");
|
|
||||||
dup(sfd, 0);
|
|
||||||
dup(sfd, 1);
|
|
||||||
dup(sfd, 2);
|
|
||||||
system("stty tabs -onlcr -echo erase ^h intr ^?");
|
|
||||||
execvp(argv[0], argv);
|
|
||||||
fprint(2, "exec %s failed: %r\n", argv[0]);
|
|
||||||
_exits("oops");
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
fatal("proc failed: %r");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
close(fd[0]);
|
|
||||||
fd[0] = fd[1];
|
|
||||||
|
|
||||||
rcpid = pid;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
tcheck(void)
|
tcheck(void)
|
||||||
{
|
{
|
||||||
|
@ -1421,7 +1530,7 @@ scrdraw(void)
|
||||||
freeimage(scrx);
|
freeimage(scrx);
|
||||||
scrx = allocimage(display, Rect(0, 0, 32, r.max.y), screen->chan, 1, DPaleyellow);
|
scrx = allocimage(display, Rect(0, 0, 32, r.max.y), screen->chan, 1, DPaleyellow);
|
||||||
if(scrx == 0)
|
if(scrx == 0)
|
||||||
fatal("scroll balloc");
|
sysfatal("scroll balloc");
|
||||||
}
|
}
|
||||||
r1.min.x = 0;
|
r1.min.x = 0;
|
||||||
r1.max.x = Dx(r);
|
r1.max.x = Dx(r);
|
||||||
|
@ -1525,16 +1634,11 @@ plumb(uint q0, uint q1)
|
||||||
char *p;
|
char *p;
|
||||||
int i, p0, n;
|
int i, p0, n;
|
||||||
char cbuf[100];
|
char cbuf[100];
|
||||||
char *w;
|
|
||||||
|
|
||||||
if(getchildwd(rcpid, childwdir, sizeof childwdir) == 0)
|
|
||||||
w = childwdir;
|
|
||||||
else
|
|
||||||
w = wdir;
|
|
||||||
pm = malloc(sizeof(Plumbmsg));
|
pm = malloc(sizeof(Plumbmsg));
|
||||||
pm->src = strdup("9term");
|
pm->src = strdup("9term");
|
||||||
pm->dst = 0;
|
pm->dst = 0;
|
||||||
pm->wdir = strdup(w);
|
pm->wdir = strdup(wdir);
|
||||||
pm->type = strdup("text");
|
pm->type = strdup("text");
|
||||||
pm->data = nil;
|
pm->data = nil;
|
||||||
if(q1 > q0)
|
if(q1 > q0)
|
||||||
|
|
|
@ -1,19 +1,4 @@
|
||||||
#include <u.h>
|
|
||||||
#include <libc.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <draw.h>
|
|
||||||
#include <thread.h>
|
|
||||||
#include <mouse.h>
|
|
||||||
#include <cursor.h>
|
|
||||||
#include <keyboard.h>
|
|
||||||
#include <frame.h>
|
|
||||||
#include <plumb.h>
|
|
||||||
#include <termios.h>
|
|
||||||
#include <sys/termios.h>
|
|
||||||
#ifdef __linux__
|
|
||||||
#include <pty.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int getchildwd(int, char*, int);
|
|
||||||
extern int getpts(int[], char*);
|
extern int getpts(int[], char*);
|
||||||
|
extern int childpty(int[], char*);
|
||||||
|
extern void updatewinsize(int, int, int, int);
|
||||||
|
extern int rcfd[];
|
||||||
|
|
|
@ -1,17 +1,43 @@
|
||||||
#include "9term.h"
|
#include "9term.h"
|
||||||
|
#include <termios.h>
|
||||||
|
#include <sys/termios.h>
|
||||||
#include <libutil.h>
|
#include <libutil.h>
|
||||||
|
|
||||||
int
|
|
||||||
getchildwd(int pid, char *wdir, int bufn)
|
|
||||||
{
|
|
||||||
USED(pid);
|
|
||||||
USED(wdir);
|
|
||||||
USED(bufn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
getpts(int fd[], char *slave)
|
getpts(int fd[], char *slave)
|
||||||
{
|
{
|
||||||
return openpty(&fd[1], &fd[0], slave, 0, 0);
|
return openpty(&fd[1], &fd[0], slave, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
childpty(int fd[], char *slave)
|
||||||
|
{
|
||||||
|
int sfd;
|
||||||
|
|
||||||
|
close(fd[1]);
|
||||||
|
setsid();
|
||||||
|
sfd = open(slave, ORDWR);
|
||||||
|
if(sfd < 0)
|
||||||
|
sysfatal("open %s: %r\n", slave);
|
||||||
|
if(ioctl(sfd, TIOCSCTTY, 0) < 0)
|
||||||
|
fprint(2, "ioctl TIOCSCTTY: %r\n");
|
||||||
|
return sfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct winsize ows;
|
||||||
|
|
||||||
|
void
|
||||||
|
updatewinsize(int row, int col, int dx, int dy)
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
ws.ws_row = row;
|
||||||
|
ws.ws_col = col;
|
||||||
|
ws.ws_xpixel = dx;
|
||||||
|
ws.ws_ypixel = dy;
|
||||||
|
if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col)
|
||||||
|
if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0)
|
||||||
|
fprint(2, "ioctl: %r\n");
|
||||||
|
ows = ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,22 +1,46 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <sys/termios.h>
|
||||||
|
#include <pty.h>
|
||||||
|
#include <libc.h>
|
||||||
#include "9term.h"
|
#include "9term.h"
|
||||||
|
|
||||||
int
|
|
||||||
getchildwd(int pid, char *wdir, int bufn)
|
|
||||||
{
|
|
||||||
char path[256];
|
|
||||||
int n;
|
|
||||||
|
|
||||||
snprint(path, sizeof path, "/proc/%d/cwd", pid);
|
|
||||||
n = readlink(path, wdir, bufn);
|
|
||||||
if(n < 0)
|
|
||||||
return -1;
|
|
||||||
wdir[n] = '\0';
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
getpts(int fd[], char *slave)
|
getpts(int fd[], char *slave)
|
||||||
{
|
{
|
||||||
openpty(&fd[1], &fd[0], slave, 0, 0);
|
openpty(&fd[1], &fd[0], slave, 0, 0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
childpty(int fd[], char *slave)
|
||||||
|
{
|
||||||
|
int sfd;
|
||||||
|
|
||||||
|
close(fd[1]);
|
||||||
|
setsid();
|
||||||
|
sfd = open(slave, ORDWR);
|
||||||
|
if(sfd < 0)
|
||||||
|
sysfatal("open %s: %r\n", slave);
|
||||||
|
if(ioctl(sfd, TIOCSCTTY, 0) < 0)
|
||||||
|
fprint(2, "ioctl TIOCSCTTY: %r\n");
|
||||||
|
return sfd;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct winsize ows;
|
||||||
|
|
||||||
|
void
|
||||||
|
updatewinsize(int row, int col, int dx, int dy)
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
ws.ws_row = row;
|
||||||
|
ws.ws_col = col;
|
||||||
|
ws.ws_xpixel = dx;
|
||||||
|
ws.ws_ypixel = dy;
|
||||||
|
if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col)
|
||||||
|
if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0)
|
||||||
|
fprint(2, "ioctl: %r\n");
|
||||||
|
ows = ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,6 @@
|
||||||
#include "9term.h"
|
#include "9term.h"
|
||||||
|
#include <termios.h>
|
||||||
int
|
#include <sys/termios.h>
|
||||||
getchildwd(int pid, char *wdir, int bufn)
|
|
||||||
{
|
|
||||||
char path[256];
|
|
||||||
char cwd[256];
|
|
||||||
|
|
||||||
if(getcwd(cwd, sizeof cwd) < 0)
|
|
||||||
return -1;
|
|
||||||
snprint(path, sizeof path, "/proc/%d/cwd", pid);
|
|
||||||
if(chdir(path) < 0)
|
|
||||||
return -1;
|
|
||||||
if(getcwd(wdir, bufn) < 0)
|
|
||||||
return -1;
|
|
||||||
chdir(cwd);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
getpts(int fd[], char *slave)
|
getpts(int fd[], char *slave)
|
||||||
|
@ -28,3 +13,21 @@ getpts(int fd[], char *slave)
|
||||||
fd[0] = open(slave, OREAD);
|
fd[0] = open(slave, OREAD);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct winsize ows;
|
||||||
|
|
||||||
|
void
|
||||||
|
updatewinsize(int row, int col, int dx, int dy)
|
||||||
|
{
|
||||||
|
struct winsize ws;
|
||||||
|
|
||||||
|
ws.ws_row = row;
|
||||||
|
ws.ws_col = col;
|
||||||
|
ws.ws_xpixel = dx;
|
||||||
|
ws.ws_ypixel = dy;
|
||||||
|
if(ws.ws_row != ows.ws_row || ws.ws_col != ows.ws_col)
|
||||||
|
if(ioctl(rcfd[0], TIOCSWINSZ, &ws) < 0)
|
||||||
|
fprint(2, "ioctl: %r\n");
|
||||||
|
ows = ws;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
PLAN9=../../..
|
PLAN9=../../..
|
||||||
<$PLAN9/src/mkhdr
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
TARG=9term
|
TARG=9term win
|
||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
9term.$O\
|
rcstart.$O\
|
||||||
$SYSNAME.$O\
|
$SYSNAME.$O\
|
||||||
|
|
||||||
SHORTLIB=frame draw plumb fs mux thread 9
|
SHORTLIB=complete frame draw plumb fs mux thread 9
|
||||||
|
|
||||||
<$PLAN9/src/mkone
|
<$PLAN9/src/mkmany
|
||||||
|
|
||||||
LDFLAGS=-L$X11/lib -lX11 -lutil
|
LDFLAGS=-L$X11/lib -lX11 -lutil
|
||||||
|
|
||||||
|
|
51
src/cmd/9term/rcstart.c
Normal file
51
src/cmd/9term/rcstart.c
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include "term.h"
|
||||||
|
|
||||||
|
int
|
||||||
|
rcstart(int argc, char **argv, int *pfd)
|
||||||
|
{
|
||||||
|
int pid;
|
||||||
|
int fd[2];
|
||||||
|
char *xargv[3];
|
||||||
|
char slave[256];
|
||||||
|
int sfd;
|
||||||
|
|
||||||
|
if(argc == 0){
|
||||||
|
argc = 2;
|
||||||
|
argv = xargv;
|
||||||
|
argv[0] = getenv("SHELL");
|
||||||
|
if(argv[0] == 0)
|
||||||
|
argv[0] = "rc";
|
||||||
|
argv[1] = "-i";
|
||||||
|
argv[2] = 0;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* fd0 is slave (tty), fd1 is master (pty)
|
||||||
|
*/
|
||||||
|
fd[0] = fd[1] = -1;
|
||||||
|
if(getpts(fd, slave) < 0)
|
||||||
|
fprint(2, "getpts: %r\n");
|
||||||
|
|
||||||
|
|
||||||
|
switch(pid = fork()) {
|
||||||
|
case 0:
|
||||||
|
putenv("TERM", "9term");
|
||||||
|
sfd = childpty(fd, slave);
|
||||||
|
dup(sfd, 0);
|
||||||
|
dup(sfd, 1);
|
||||||
|
dup(sfd, 2);
|
||||||
|
system("stty tabs -onlcr -echo erase ^h intr ^?");
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
fprint(2, "exec %s failed: %r\n", argv[0]);
|
||||||
|
_exits("oops");
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
sysfatal("proc failed: %r");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
close(fd[0]);
|
||||||
|
*pfd = fd[1];
|
||||||
|
return pid;
|
||||||
|
}
|
||||||
|
|
5
src/cmd/9term/term.h
Normal file
5
src/cmd/9term/term.h
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
extern int getpts(int[], char*);
|
||||||
|
extern int childpty(int[], char*);
|
||||||
|
extern void updatewinsize(int, int, int, int);
|
||||||
|
extern int rcfd;
|
||||||
|
extern int rcstart(int, char*[], int*);
|
|
@ -3,6 +3,7 @@
|
||||||
#include <thread.h>
|
#include <thread.h>
|
||||||
#include <fcall.h>
|
#include <fcall.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
|
#include "term.h"
|
||||||
|
|
||||||
#define EVENTSIZE 256
|
#define EVENTSIZE 256
|
||||||
#define STACK 32768
|
#define STACK 32768
|
||||||
|
@ -51,11 +52,11 @@ int ntypeb;
|
||||||
int ntyper;
|
int ntyper;
|
||||||
int ntypebreak;
|
int ntypebreak;
|
||||||
int debug;
|
int debug;
|
||||||
|
int rcfd;
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
char **prog;
|
char **prog;
|
||||||
int p[2];
|
|
||||||
Channel *cpid;
|
|
||||||
Channel *cwait;
|
Channel *cwait;
|
||||||
int pid = -1;
|
int pid = -1;
|
||||||
|
|
||||||
|
@ -124,9 +125,11 @@ threadmain(int argc, char **argv)
|
||||||
|
|
||||||
prog = argv;
|
prog = argv;
|
||||||
|
|
||||||
if(argc > 0)
|
if(argc > 0){
|
||||||
name = argv[0];
|
name = argv[0];
|
||||||
else
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}else
|
||||||
name = "gnot";
|
name = "gnot";
|
||||||
|
|
||||||
threadnotify(nopipes, 1);
|
threadnotify(nopipes, 1);
|
||||||
|
@ -156,14 +159,9 @@ threadmain(int argc, char **argv)
|
||||||
*/
|
*/
|
||||||
fsunmount(fs);
|
fsunmount(fs);
|
||||||
|
|
||||||
if(pipe(p) < 0)
|
|
||||||
sysfatal("pipe: %r");
|
|
||||||
|
|
||||||
cpid = chancreate(sizeof(ulong), 1);
|
|
||||||
cwait = threadwaitchan();
|
cwait = threadwaitchan();
|
||||||
threadcreate(waitthread, nil, STACK);
|
threadcreate(waitthread, nil, STACK);
|
||||||
threadcreate(runproc, nil, STACK);
|
pid = rcstart(argc, argv, &rcfd);
|
||||||
pid = recvul(cpid);
|
|
||||||
if(pid == -1)
|
if(pid == -1)
|
||||||
sysfatal("exec failed");
|
sysfatal("exec failed");
|
||||||
|
|
||||||
|
@ -179,30 +177,6 @@ threadmain(int argc, char **argv)
|
||||||
stdinproc(nil);
|
stdinproc(nil);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *shell[] = { "rc", "-i", 0 };
|
|
||||||
void
|
|
||||||
runproc(void *v)
|
|
||||||
{
|
|
||||||
int fd[3];
|
|
||||||
char *sh;
|
|
||||||
|
|
||||||
USED(v);
|
|
||||||
|
|
||||||
fd[0] = p[1];
|
|
||||||
// fd[1] = bodyfd;
|
|
||||||
// fd[2] = bodyfd;
|
|
||||||
fd[1] = p[1];
|
|
||||||
fd[2] = p[1];
|
|
||||||
|
|
||||||
if(prog[0] == nil){
|
|
||||||
prog = shell;
|
|
||||||
if((sh = getenv("SHELL")) != nil)
|
|
||||||
shell[0] = sh;
|
|
||||||
}
|
|
||||||
threadexec(cpid, fd, prog[0], prog);
|
|
||||||
threadexits(nil);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
error(char *s)
|
error(char *s)
|
||||||
{
|
{
|
||||||
|
@ -329,7 +303,7 @@ stdinproc(void *v)
|
||||||
Fid *efd = eventfd;
|
Fid *efd = eventfd;
|
||||||
Fid *dfd = datafd;
|
Fid *dfd = datafd;
|
||||||
Fid *afd = addrfd;
|
Fid *afd = addrfd;
|
||||||
int fd0 = p[0];
|
int fd0 = rcfd;
|
||||||
Event e, e2, e3, e4;
|
Event e, e2, e3, e4;
|
||||||
|
|
||||||
USED(v);
|
USED(v);
|
||||||
|
@ -426,7 +400,7 @@ stdinproc(void *v)
|
||||||
void
|
void
|
||||||
stdoutproc(void *v)
|
stdoutproc(void *v)
|
||||||
{
|
{
|
||||||
int fd1 = p[0];
|
int fd1 = rcfd;
|
||||||
Fid *afd = addrfd;
|
Fid *afd = addrfd;
|
||||||
Fid *dfd = datafd;
|
Fid *dfd = datafd;
|
||||||
int n, m, w, npart;
|
int n, m, w, npart;
|
||||||
|
@ -439,6 +413,8 @@ stdoutproc(void *v)
|
||||||
buf = malloc(8192+UTFmax+1);
|
buf = malloc(8192+UTFmax+1);
|
||||||
npart = 0;
|
npart = 0;
|
||||||
for(;;){
|
for(;;){
|
||||||
|
/* Let typing have a go -- maybe there's a rubout waiting. */
|
||||||
|
yield();
|
||||||
n = threadread(fd1, buf+npart, 8192);
|
n = threadread(fd1, buf+npart, 8192);
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
error(nil);
|
error(nil);
|
||||||
|
@ -556,7 +532,7 @@ addtype(int c, uint p0, char *b, int nb, int nr)
|
||||||
for(i=0; i<nb; i+=w){
|
for(i=0; i<nb; i+=w){
|
||||||
w = chartorune(&r, b+i);
|
w = chartorune(&r, b+i);
|
||||||
if((r==0x7F||r==3) && c=='K'){
|
if((r==0x7F||r==3) && c=='K'){
|
||||||
postnote(PNGROUP, pid, "interrupt");
|
write(rcfd, "\x7F", 1);
|
||||||
/* toss all typing */
|
/* toss all typing */
|
||||||
q.p += ntyper+nr;
|
q.p += ntyper+nr;
|
||||||
ntypebreak = 0;
|
ntypebreak = 0;
|
|
@ -161,7 +161,8 @@ threadmain(int argc, char *argv[])
|
||||||
cerr = chancreate(sizeof(char*), 0);
|
cerr = chancreate(sizeof(char*), 0);
|
||||||
cedit = chancreate(sizeof(int), 0);
|
cedit = chancreate(sizeof(int), 0);
|
||||||
cexit = chancreate(sizeof(int), 0);
|
cexit = chancreate(sizeof(int), 0);
|
||||||
if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil){
|
cwarn = chancreate(sizeof(void*), 1);
|
||||||
|
if(cwait==nil || ccommand==nil || ckill==nil || cxfidalloc==nil || cxfidfree==nil || cerr==nil || cexit==nil || cwarn==nil){
|
||||||
fprint(2, "acme: can't create initial channels: %r\n");
|
fprint(2, "acme: can't create initial channels: %r\n");
|
||||||
exits("channels");
|
exits("channels");
|
||||||
}
|
}
|
||||||
|
@ -251,7 +252,7 @@ readfile(Column *c, char *s)
|
||||||
|
|
||||||
w = coladd(c, nil, nil, -1);
|
w = coladd(c, nil, nil, -1);
|
||||||
cvttorunes(s, strlen(s), rb, &nb, &nr, nil);
|
cvttorunes(s, strlen(s), rb, &nb, &nr, nil);
|
||||||
rs = cleanrname((Runestr){rb, nr});
|
rs = cleanrname(runestr(rb, nr));
|
||||||
winsetname(w, rs.r, rs.nr);
|
winsetname(w, rs.r, rs.nr);
|
||||||
textload(&w->body, 0, s, 1);
|
textload(&w->body, 0, s, 1);
|
||||||
w->body.file->mod = FALSE;
|
w->body.file->mod = FALSE;
|
||||||
|
@ -403,7 +404,6 @@ keyboardthread(void *v)
|
||||||
winlock(t->w, 'K');
|
winlock(t->w, 'K');
|
||||||
wincommit(t->w, t);
|
wincommit(t->w, t);
|
||||||
winunlock(t->w);
|
winunlock(t->w);
|
||||||
flushwarnings(1);
|
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
}
|
}
|
||||||
alts[KTimer].c = nil;
|
alts[KTimer].c = nil;
|
||||||
|
@ -430,7 +430,6 @@ keyboardthread(void *v)
|
||||||
}
|
}
|
||||||
if(nbrecv(keyboardctl->c, &r) > 0)
|
if(nbrecv(keyboardctl->c, &r) > 0)
|
||||||
goto casekeyboard;
|
goto casekeyboard;
|
||||||
flushwarnings(1);
|
|
||||||
flushimage(display, 1);
|
flushimage(display, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -447,7 +446,7 @@ mousethread(void *v)
|
||||||
Plumbmsg *pm;
|
Plumbmsg *pm;
|
||||||
Mouse m;
|
Mouse m;
|
||||||
char *act;
|
char *act;
|
||||||
enum { MResize, MMouse, MPlumb, NMALT };
|
enum { MResize, MMouse, MPlumb, MWarnings, NMALT };
|
||||||
static Alt alts[NMALT+1];
|
static Alt alts[NMALT+1];
|
||||||
|
|
||||||
USED(v);
|
USED(v);
|
||||||
|
@ -461,11 +460,18 @@ mousethread(void *v)
|
||||||
alts[MPlumb].c = cplumb;
|
alts[MPlumb].c = cplumb;
|
||||||
alts[MPlumb].v = ±
|
alts[MPlumb].v = ±
|
||||||
alts[MPlumb].op = CHANRCV;
|
alts[MPlumb].op = CHANRCV;
|
||||||
|
alts[MWarnings].c = cwarn;
|
||||||
|
alts[MWarnings].v = nil;
|
||||||
|
alts[MWarnings].op = CHANRCV;
|
||||||
if(cplumb == nil)
|
if(cplumb == nil)
|
||||||
alts[MPlumb].op = CHANNOP;
|
alts[MPlumb].op = CHANNOP;
|
||||||
alts[NMALT].op = CHANEND;
|
alts[NMALT].op = CHANEND;
|
||||||
|
|
||||||
for(;;){
|
for(;;){
|
||||||
|
qlock(&row.lk);
|
||||||
|
flushwarnings();
|
||||||
|
qunlock(&row.lk);
|
||||||
|
flushimage(display, 1);
|
||||||
switch(alt(alts)){
|
switch(alt(alts)){
|
||||||
case MResize:
|
case MResize:
|
||||||
if(getwindow(display, Refnone) < 0)
|
if(getwindow(display, Refnone) < 0)
|
||||||
|
@ -473,8 +479,6 @@ mousethread(void *v)
|
||||||
draw(screen, screen->r, display->white, nil, ZP);
|
draw(screen, screen->r, display->white, nil, ZP);
|
||||||
scrlresize();
|
scrlresize();
|
||||||
rowresize(&row, screen->clipr);
|
rowresize(&row, screen->clipr);
|
||||||
flushwarnings(1);
|
|
||||||
flushimage(display, 1);
|
|
||||||
break;
|
break;
|
||||||
case MPlumb:
|
case MPlumb:
|
||||||
if(strcmp(pm->type, "text") == 0){
|
if(strcmp(pm->type, "text") == 0){
|
||||||
|
@ -484,10 +488,10 @@ mousethread(void *v)
|
||||||
else if(strcmp(act, "showdata")==0)
|
else if(strcmp(act, "showdata")==0)
|
||||||
plumbshow(pm);
|
plumbshow(pm);
|
||||||
}
|
}
|
||||||
flushwarnings(1);
|
|
||||||
flushimage(display, 1);
|
|
||||||
plumbfree(pm);
|
plumbfree(pm);
|
||||||
break;
|
break;
|
||||||
|
case MWarnings:
|
||||||
|
break;
|
||||||
case MMouse:
|
case MMouse:
|
||||||
/*
|
/*
|
||||||
* Make a copy so decisions are consistent; mousectl changes
|
* Make a copy so decisions are consistent; mousectl changes
|
||||||
|
@ -570,8 +574,6 @@ mousethread(void *v)
|
||||||
goto Continue;
|
goto Continue;
|
||||||
}
|
}
|
||||||
Continue:
|
Continue:
|
||||||
flushwarnings(0);
|
|
||||||
flushimage(display, 1);
|
|
||||||
qunlock(&row.lk);
|
qunlock(&row.lk);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -543,5 +543,6 @@ Channel *mouseexit1; /* chan(int) */
|
||||||
Channel *cexit; /* chan(int) */
|
Channel *cexit; /* chan(int) */
|
||||||
Channel *cerr; /* chan(char*) */
|
Channel *cerr; /* chan(char*) */
|
||||||
Channel *cedit; /* chan(int) */
|
Channel *cedit; /* chan(int) */
|
||||||
|
Channel *cwarn; /* chan(void*)[1] (really chan(unit)[1]) */
|
||||||
|
|
||||||
#define STACK 32768
|
#define STACK 32768
|
||||||
|
|
|
@ -268,7 +268,7 @@ D_cmd(Text *t, Cmd *cp)
|
||||||
runemove(n, dir.r, dir.nr);
|
runemove(n, dir.r, dir.nr);
|
||||||
n[dir.nr] = '/';
|
n[dir.nr] = '/';
|
||||||
runemove(n+dir.nr+1, r, nn);
|
runemove(n+dir.nr+1, r, nn);
|
||||||
rs = cleanrname((Runestr){n, dir.nr+1+nn});
|
rs = cleanrname(runestr(n, dir.nr+1+nn));
|
||||||
}
|
}
|
||||||
w = lookfile(rs.r, rs.nr);
|
w = lookfile(rs.r, rs.nr);
|
||||||
if(w == nil){
|
if(w == nil){
|
||||||
|
|
|
@ -25,6 +25,7 @@ void fontx(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void get(Text*, Text*, Text*, int, int, Rune*, int);
|
void get(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void id(Text*, Text*, Text*, int, int, Rune*, int);
|
void id(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void incl(Text*, Text*, Text*, int, int, Rune*, int);
|
void incl(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
|
void indent(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void xkill(Text*, Text*, Text*, int, int, Rune*, int);
|
void xkill(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void local(Text*, Text*, Text*, int, int, Rune*, int);
|
void local(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
void look(Text*, Text*, Text*, int, int, Rune*, int);
|
void look(Text*, Text*, Text*, int, int, Rune*, int);
|
||||||
|
@ -58,6 +59,7 @@ static Rune LFont[] = { 'F', 'o', 'n', 't', 0 };
|
||||||
static Rune LGet[] = { 'G', 'e', 't', 0 };
|
static Rune LGet[] = { 'G', 'e', 't', 0 };
|
||||||
static Rune LID[] = { 'I', 'D', 0 };
|
static Rune LID[] = { 'I', 'D', 0 };
|
||||||
static Rune LIncl[] = { 'I', 'n', 'c', 'l', 0 };
|
static Rune LIncl[] = { 'I', 'n', 'c', 'l', 0 };
|
||||||
|
static Rune LIndent[] = { 'I', 'n', 'd', 'e', 'n', 't', 0 };
|
||||||
static Rune LKill[] = { 'K', 'i', 'l', 'l', 0 };
|
static Rune LKill[] = { 'K', 'i', 'l', 'l', 0 };
|
||||||
static Rune LLoad[] = { 'L', 'o', 'a', 'd', 0 };
|
static Rune LLoad[] = { 'L', 'o', 'a', 'd', 0 };
|
||||||
static Rune LLocal[] = { 'L', 'o', 'c', 'a', 'l', 0 };
|
static Rune LLocal[] = { 'L', 'o', 'c', 'a', 'l', 0 };
|
||||||
|
@ -87,6 +89,7 @@ Exectab exectab[] = {
|
||||||
{ LGet, get, FALSE, TRUE, XXX },
|
{ LGet, get, FALSE, TRUE, XXX },
|
||||||
{ LID, id, FALSE, XXX, XXX },
|
{ LID, id, FALSE, XXX, XXX },
|
||||||
{ LIncl, incl, FALSE, XXX, XXX },
|
{ LIncl, incl, FALSE, XXX, XXX },
|
||||||
|
{ LIndent, indent, FALSE, XXX, XXX },
|
||||||
{ LKill, xkill, FALSE, XXX, XXX },
|
{ LKill, xkill, FALSE, XXX, XXX },
|
||||||
{ LLoad, dump, FALSE, FALSE, XXX },
|
{ LLoad, dump, FALSE, FALSE, XXX },
|
||||||
{ LLocal, local, FALSE, XXX, XXX },
|
{ LLocal, local, FALSE, XXX, XXX },
|
||||||
|
@ -1443,7 +1446,6 @@ runproc(void *argvp)
|
||||||
goto Fail;
|
goto Fail;
|
||||||
|
|
||||||
Hard:
|
Hard:
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ugly: set path = (. $cputype /bin)
|
* ugly: set path = (. $cputype /bin)
|
||||||
* should honor $path if unusual.
|
* should honor $path if unusual.
|
||||||
|
|
|
@ -69,6 +69,7 @@ Rune* bytetorune(char*, int*);
|
||||||
void fsysinit(void);
|
void fsysinit(void);
|
||||||
Mntdir* fsysmount(Rune*, int, Rune**, int);
|
Mntdir* fsysmount(Rune*, int, Rune**, int);
|
||||||
void fsysdelid(Mntdir*);
|
void fsysdelid(Mntdir*);
|
||||||
|
void fsysincid(Mntdir*);
|
||||||
Xfid* respond(Xfid*, Fcall*, char*);
|
Xfid* respond(Xfid*, Fcall*, char*);
|
||||||
int rxcompile(Rune*);
|
int rxcompile(Rune*);
|
||||||
int rgetc(void*, uint);
|
int rgetc(void*, uint);
|
||||||
|
@ -86,9 +87,11 @@ int expand(Text*, uint, uint, Expand*);
|
||||||
Rune* skipbl(Rune*, int, int*);
|
Rune* skipbl(Rune*, int, int*);
|
||||||
Rune* findbl(Rune*, int, int*);
|
Rune* findbl(Rune*, int, int*);
|
||||||
char* edittext(Window*, int, Rune*, int);
|
char* edittext(Window*, int, Rune*, int);
|
||||||
void flushwarnings(int);
|
void flushwarnings(void);
|
||||||
void startplumbing(void);
|
void startplumbing(void);
|
||||||
|
|
||||||
|
Runestr runestr(Rune*, uint);
|
||||||
|
|
||||||
#define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
|
#define runemalloc(a) (Rune*)emalloc((a)*sizeof(Rune))
|
||||||
#define runerealloc(a, b) (Rune*)erealloc((a), (b)*sizeof(Rune))
|
#define runerealloc(a, b) (Rune*)erealloc((a), (b)*sizeof(Rune))
|
||||||
#define runemove(a, b, c) memmove((a), (b), (c)*sizeof(Rune))
|
#define runemove(a, b, c) memmove((a), (b), (c)*sizeof(Rune))
|
||||||
|
|
|
@ -37,22 +37,25 @@ static Xfid* fsysremove(Xfid*, Fid*);
|
||||||
static Xfid* fsysstat(Xfid*, Fid*);
|
static Xfid* fsysstat(Xfid*, Fid*);
|
||||||
static Xfid* fsyswstat(Xfid*, Fid*);
|
static Xfid* fsyswstat(Xfid*, Fid*);
|
||||||
|
|
||||||
Xfid* (*fcall[Tmax])(Xfid*, Fid*) =
|
Xfid* (*fcall[Tmax])(Xfid*, Fid*);
|
||||||
|
|
||||||
|
static void
|
||||||
|
initfcall(void)
|
||||||
{
|
{
|
||||||
[Tflush] = fsysflush,
|
fcall[Tflush] = fsysflush;
|
||||||
[Tversion] = fsysversion,
|
fcall[Tversion] = fsysversion;
|
||||||
[Tauth] = fsysauth,
|
fcall[Tauth] = fsysauth;
|
||||||
[Tattach] = fsysattach,
|
fcall[Tattach] = fsysattach;
|
||||||
[Twalk] = fsyswalk,
|
fcall[Twalk] = fsyswalk;
|
||||||
[Topen] = fsysopen,
|
fcall[Topen] = fsysopen;
|
||||||
[Tcreate] = fsyscreate,
|
fcall[Tcreate] = fsyscreate;
|
||||||
[Tread] = fsysread,
|
fcall[Tread] = fsysread;
|
||||||
[Twrite] = fsyswrite,
|
fcall[Twrite] = fsyswrite;
|
||||||
[Tclunk] = fsysclunk,
|
fcall[Tclunk] = fsysclunk;
|
||||||
[Tremove]= fsysremove,
|
fcall[Tremove]= fsysremove;
|
||||||
[Tstat] = fsysstat,
|
fcall[Tstat] = fsysstat;
|
||||||
[Twstat] = fsyswstat,
|
fcall[Twstat] = fsyswstat;
|
||||||
};
|
}
|
||||||
|
|
||||||
char Eperm[] = "permission denied";
|
char Eperm[] = "permission denied";
|
||||||
char Eexist[] = "file does not exist";
|
char Eexist[] = "file does not exist";
|
||||||
|
@ -113,6 +116,7 @@ fsysinit(void)
|
||||||
int p[2];
|
int p[2];
|
||||||
char *u;
|
char *u;
|
||||||
|
|
||||||
|
initfcall();
|
||||||
if(pipe(p) < 0)
|
if(pipe(p) < 0)
|
||||||
error("can't create pipe");
|
error("can't create pipe");
|
||||||
if(post9pservice(p[0], "acme") < 0)
|
if(post9pservice(p[0], "acme") < 0)
|
||||||
|
@ -186,6 +190,14 @@ fsysaddid(Rune *dir, int ndir, Rune **incl, int nincl)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fsysincid(Mntdir *m)
|
||||||
|
{
|
||||||
|
qlock(&mnt.lk);
|
||||||
|
m->ref++;
|
||||||
|
qunlock(&mnt.lk);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
fsysdelid(Mntdir *idm)
|
fsysdelid(Mntdir *idm)
|
||||||
{
|
{
|
||||||
|
@ -331,7 +343,7 @@ fsysattach(Xfid *x, Fid *f)
|
||||||
m->ref++;
|
m->ref++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(m == nil){
|
if(m == nil && x->fcall.aname[0]){
|
||||||
snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
|
snprint(buf, sizeof buf, "unknown id '%s' in attach", x->fcall.aname);
|
||||||
sendp(cerr, estrdup(buf));
|
sendp(cerr, estrdup(buf));
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,7 @@ plumbshow(Plumbmsg *m)
|
||||||
}
|
}
|
||||||
cvttorunes(name, strlen(name), rb, &nb, &nr, nil);
|
cvttorunes(name, strlen(name), rb, &nb, &nr, nil);
|
||||||
free(p);
|
free(p);
|
||||||
rs = cleanrname((Runestr){rb, nr});
|
rs = cleanrname(runestr(rb, nr));
|
||||||
winsetname(w, rs.r, rs.nr);
|
winsetname(w, rs.r, rs.nr);
|
||||||
r = runemalloc(m->ndata);
|
r = runemalloc(m->ndata);
|
||||||
cvttorunes(m->data, m->ndata, r, &nb, &nr, nil);
|
cvttorunes(m->data, m->ndata, r, &nb, &nr, nil);
|
||||||
|
@ -385,13 +385,13 @@ includefile(Rune *dir, Rune *file, int nfile)
|
||||||
n = access(a, 0);
|
n = access(a, 0);
|
||||||
free(a);
|
free(a);
|
||||||
if(n < 0)
|
if(n < 0)
|
||||||
return (Runestr){nil, 0};
|
return runestr(nil, 0);
|
||||||
r = runemalloc(m+1+nfile);
|
r = runemalloc(m+1+nfile);
|
||||||
runemove(r, dir, m);
|
runemove(r, dir, m);
|
||||||
runemove(r+m, Lslash, 1);
|
runemove(r+m, Lslash, 1);
|
||||||
runemove(r+m+1, file, nfile);
|
runemove(r+m+1, file, nfile);
|
||||||
free(file);
|
free(file);
|
||||||
return cleanrname((Runestr){r, m+1+nfile});
|
return cleanrname(runestr(r, m+1+nfile));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Rune *objdir;
|
static Rune *objdir;
|
||||||
|
@ -442,7 +442,7 @@ includename(Text *t, Rune *r, int n)
|
||||||
return file;
|
return file;
|
||||||
|
|
||||||
Rescue:
|
Rescue:
|
||||||
return (Runestr){r, n};
|
return runestr(r, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
Runestr
|
Runestr
|
||||||
|
@ -475,11 +475,11 @@ dirname(Text *t, Rune *r, int n)
|
||||||
goto Rescue;
|
goto Rescue;
|
||||||
runemove(b+slash+1, r, n);
|
runemove(b+slash+1, r, n);
|
||||||
free(r);
|
free(r);
|
||||||
return cleanrname((Runestr){b, slash+1+n});
|
return cleanrname(runestr(b, slash+1+n));
|
||||||
|
|
||||||
Rescue:
|
Rescue:
|
||||||
free(b);
|
free(b);
|
||||||
tmp = (Runestr){r, n};
|
tmp = runestr(r, n);
|
||||||
if(r)
|
if(r)
|
||||||
return cleanrname(tmp);
|
return cleanrname(tmp);
|
||||||
return tmp;
|
return tmp;
|
||||||
|
|
|
@ -578,7 +578,7 @@ textcomplete(Text *t)
|
||||||
path[i] = textreadc(t, q++);
|
path[i] = textreadc(t, q++);
|
||||||
/* is path rooted? if not, we need to make it relative to window path */
|
/* is path rooted? if not, we need to make it relative to window path */
|
||||||
if(npath>0 && path[0]=='/')
|
if(npath>0 && path[0]=='/')
|
||||||
dir = (Runestr){path, npath};
|
dir = runestr(path, npath);
|
||||||
else{
|
else{
|
||||||
dir = dirname(t, nil, 0);
|
dir = dirname(t, nil, 0);
|
||||||
if(dir.nr + 1 + npath > nelem(tmp)){
|
if(dir.nr + 1 + npath > nelem(tmp)){
|
||||||
|
|
|
@ -14,6 +14,16 @@
|
||||||
static Point prevmouse;
|
static Point prevmouse;
|
||||||
static Window *mousew;
|
static Window *mousew;
|
||||||
|
|
||||||
|
Runestr
|
||||||
|
runestr(Rune *r, uint n)
|
||||||
|
{
|
||||||
|
Runestr rs;
|
||||||
|
|
||||||
|
rs.r = r;
|
||||||
|
rs.nr = n;
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
|
cvttorunes(char *p, int n, Rune *r, int *nb, int *nr, int *nulls)
|
||||||
{
|
{
|
||||||
|
@ -133,12 +143,17 @@ addwarningtext(Mntdir *md, Rune *r, int nr)
|
||||||
}
|
}
|
||||||
warn = emalloc(sizeof(Warning));
|
warn = emalloc(sizeof(Warning));
|
||||||
warn->next = warnings;
|
warn->next = warnings;
|
||||||
|
warn->md = md;
|
||||||
|
if(md)
|
||||||
|
fsysincid(md);
|
||||||
warnings = warn;
|
warnings = warn;
|
||||||
bufinsert(&warn->buf, 0, r, nr);
|
bufinsert(&warn->buf, 0, r, nr);
|
||||||
|
nbsendp(cwarn, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* called while row is locked */
|
||||||
void
|
void
|
||||||
flushwarnings(int dolock)
|
flushwarnings(void)
|
||||||
{
|
{
|
||||||
Warning *warn, *next;
|
Warning *warn, *next;
|
||||||
Window *w;
|
Window *w;
|
||||||
|
@ -146,8 +161,6 @@ flushwarnings(int dolock)
|
||||||
int owner, nr, q0, n;
|
int owner, nr, q0, n;
|
||||||
Rune *r;
|
Rune *r;
|
||||||
|
|
||||||
if(dolock)
|
|
||||||
qlock(&row.lk);
|
|
||||||
if(row.ncol == 0){ /* really early error */
|
if(row.ncol == 0){ /* really early error */
|
||||||
rowinit(&row, screen->clipr);
|
rowinit(&row, screen->clipr);
|
||||||
rowadd(&row, nil, -1);
|
rowadd(&row, nil, -1);
|
||||||
|
@ -189,11 +202,11 @@ flushwarnings(int dolock)
|
||||||
winunlock(w);
|
winunlock(w);
|
||||||
bufclose(&warn->buf);
|
bufclose(&warn->buf);
|
||||||
next = warn->next;
|
next = warn->next;
|
||||||
|
if(warn->md)
|
||||||
|
fsysdelid(warn->md);
|
||||||
free(warn);
|
free(warn);
|
||||||
}
|
}
|
||||||
warnings = nil;
|
warnings = nil;
|
||||||
if(dolock)
|
|
||||||
qunlock(&row.lk);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -543,7 +543,6 @@ xfidwrite(Xfid *x)
|
||||||
}
|
}
|
||||||
if(w)
|
if(w)
|
||||||
winunlock(w);
|
winunlock(w);
|
||||||
flushwarnings(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -814,7 +813,6 @@ xfideventwrite(Xfid *x, Window *w)
|
||||||
qunlock(&row.lk);
|
qunlock(&row.lk);
|
||||||
goto Rescue;
|
goto Rescue;
|
||||||
}
|
}
|
||||||
flushwarnings(0);
|
|
||||||
qunlock(&row.lk);
|
qunlock(&row.lk);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1032,7 +1030,6 @@ xfidindexread(Xfid *x)
|
||||||
b[n++] = '\n';
|
b[n++] = '\n';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
flushwarnings(0);
|
|
||||||
qunlock(&row.lk);
|
qunlock(&row.lk);
|
||||||
off = x->fcall.offset;
|
off = x->fcall.offset;
|
||||||
cnt = x->fcall.count;
|
cnt = x->fcall.count;
|
||||||
|
|
|
@ -119,6 +119,8 @@ main(int argc, char **argv)
|
||||||
line = malloc(strlen(p)+5);
|
line = malloc(strlen(p)+5);
|
||||||
sprint(line, "/%s/P\n", p);
|
sprint(line, "/%s/P\n", p);
|
||||||
}
|
}
|
||||||
|
dict->path = unsharp(dict->path);
|
||||||
|
dict->indexpath = unsharp(dict->indexpath);
|
||||||
bdict = Bopen(dict->path, OREAD);
|
bdict = Bopen(dict->path, OREAD);
|
||||||
if(!bdict) {
|
if(!bdict) {
|
||||||
err("can't open dictionary %s", dict->path);
|
err("can't open dictionary %s", dict->path);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#define stdout bstdout
|
||||||
|
|
||||||
char mode; /* '\0', 'e', 'f', 'h' */
|
char mode; /* '\0', 'e', 'f', 'h' */
|
||||||
char bflag; /* ignore multiple and trailing blanks */
|
char bflag; /* ignore multiple and trailing blanks */
|
||||||
char rflag; /* recurse down directory trees */
|
char rflag; /* recurse down directory trees */
|
||||||
|
|
|
@ -26,6 +26,8 @@ void
|
||||||
done(int status)
|
done(int status)
|
||||||
{
|
{
|
||||||
rmtmpfiles();
|
rmtmpfiles();
|
||||||
|
Bflush(&stdout);
|
||||||
|
Bterm(&stdout);
|
||||||
switch(status)
|
switch(status)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#define index findex
|
#define index findex
|
||||||
char choice[2048];
|
char choice[2048];
|
||||||
char index[] = "/sys/games/lib/fortunes.index";
|
char *index = "#9/lib/fortunes.index";
|
||||||
char fortunes[] = "/sys/games/lib/fortunes";
|
char *fortunes = "#9/lib/fortunes";
|
||||||
|
|
||||||
#define lrand rand
|
#define lrand rand
|
||||||
|
|
||||||
|
@ -21,6 +21,9 @@ main(int argc, char *argv[])
|
||||||
Dir *fbuf, *ixbuf;
|
Dir *fbuf, *ixbuf;
|
||||||
Biobuf *f, g;
|
Biobuf *f, g;
|
||||||
|
|
||||||
|
index = unsharp(index);
|
||||||
|
fortunes = unsharp(index);
|
||||||
|
|
||||||
newindex = 0;
|
newindex = 0;
|
||||||
oldindex = 0;
|
oldindex = 0;
|
||||||
ix = offs = 0;
|
ix = offs = 0;
|
||||||
|
@ -55,6 +58,7 @@ main(int argc, char *argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(oldindex){
|
if(oldindex){
|
||||||
|
srand(getpid());
|
||||||
seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
|
seek(ix, lrand()%(ixbuf->length/sizeof(offs))*sizeof(offs), 0);
|
||||||
read(ix, off, sizeof(off));
|
read(ix, off, sizeof(off));
|
||||||
Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
|
Bseek(f, off[0]|(off[1]<<8)|(off[2]<<16)|(off[3]<<24), 0);
|
||||||
|
|
277
src/cmd/grep/comp.c
Normal file
277
src/cmd/grep/comp.c
Normal file
|
@ -0,0 +1,277 @@
|
||||||
|
#include "grep.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* incremental compiler.
|
||||||
|
* add the branch c to the
|
||||||
|
* state s.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
increment(State *s, int c)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
State *t, **tt;
|
||||||
|
Re *re1, *re2;
|
||||||
|
|
||||||
|
nfollow = 0;
|
||||||
|
gen++;
|
||||||
|
matched = 0;
|
||||||
|
for(i=0; i<s->count; i++)
|
||||||
|
fol1(s->re[i], c);
|
||||||
|
qsort(follow, nfollow, sizeof(*follow), fcmp);
|
||||||
|
for(tt=&state0; t = *tt;) {
|
||||||
|
if(t->count > nfollow) {
|
||||||
|
tt = &t->linkleft;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
if(t->count < nfollow) {
|
||||||
|
tt = &t->linkright;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
for(i=0; i<nfollow; i++) {
|
||||||
|
re1 = t->re[i];
|
||||||
|
re2 = follow[i];
|
||||||
|
if(re1 > re2) {
|
||||||
|
tt = &t->linkleft;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
if(re1 < re2) {
|
||||||
|
tt = &t->linkright;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!!matched && !t->match) {
|
||||||
|
tt = &t->linkleft;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
if(!matched && !!t->match) {
|
||||||
|
tt = &t->linkright;
|
||||||
|
goto cont;
|
||||||
|
}
|
||||||
|
s->next[c] = t;
|
||||||
|
return;
|
||||||
|
cont:;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = sal(nfollow);
|
||||||
|
*tt = t;
|
||||||
|
for(i=0; i<nfollow; i++) {
|
||||||
|
re1 = follow[i];
|
||||||
|
t->re[i] = re1;
|
||||||
|
}
|
||||||
|
s->next[c] = t;
|
||||||
|
t->match = matched;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
fcmp(const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
Re **aa, **bb;
|
||||||
|
Re *a, *b;
|
||||||
|
|
||||||
|
aa = (Re**)va;
|
||||||
|
bb = (Re**)vb;
|
||||||
|
a = *aa;
|
||||||
|
b = *bb;
|
||||||
|
if(a > b)
|
||||||
|
return 1;
|
||||||
|
if(a < b)
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fol1(Re *r, int c)
|
||||||
|
{
|
||||||
|
Re *r1;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
if(r->gen == gen)
|
||||||
|
return;
|
||||||
|
if(nfollow >= maxfollow)
|
||||||
|
error("nfollow");
|
||||||
|
r->gen = gen;
|
||||||
|
switch(r->type) {
|
||||||
|
default:
|
||||||
|
error("fol1");
|
||||||
|
|
||||||
|
case Tcase:
|
||||||
|
if(c >= 0 && c < 256)
|
||||||
|
if(r1 = r->cases[c])
|
||||||
|
follow[nfollow++] = r1;
|
||||||
|
if(r = r->next)
|
||||||
|
goto loop;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Talt:
|
||||||
|
case Tor:
|
||||||
|
fol1(r->alt, c);
|
||||||
|
r = r->next;
|
||||||
|
goto loop;
|
||||||
|
|
||||||
|
case Tbegin:
|
||||||
|
if(c == '\n' || c == Cbegin)
|
||||||
|
follow[nfollow++] = r->next;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tend:
|
||||||
|
if(c == '\n')
|
||||||
|
matched = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tclass:
|
||||||
|
if(c >= r->lo && c <= r->hi)
|
||||||
|
follow[nfollow++] = r->next;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rune tab1[] =
|
||||||
|
{
|
||||||
|
0x007f,
|
||||||
|
0x07ff,
|
||||||
|
};
|
||||||
|
Rune tab2[] =
|
||||||
|
{
|
||||||
|
0x003f,
|
||||||
|
0x0fff,
|
||||||
|
};
|
||||||
|
|
||||||
|
Re2
|
||||||
|
rclass(Rune p0, Rune p1)
|
||||||
|
{
|
||||||
|
char xc0[6], xc1[6];
|
||||||
|
int i, n, m;
|
||||||
|
Re2 x;
|
||||||
|
|
||||||
|
if(p0 > p1)
|
||||||
|
return re2char(0xff, 0xff); // no match
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bust range into same length
|
||||||
|
* character sequences
|
||||||
|
*/
|
||||||
|
for(i=0; i<nelem(tab1); i++) {
|
||||||
|
m = tab1[i];
|
||||||
|
if(p0 <= m && p1 > m)
|
||||||
|
return re2or(rclass(p0, m), rclass(m+1, p1));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* bust range into part of a single page
|
||||||
|
* or into full pages
|
||||||
|
*/
|
||||||
|
for(i=0; i<nelem(tab2); i++) {
|
||||||
|
m = tab2[i];
|
||||||
|
if((p0 & ~m) != (p1 & ~m)) {
|
||||||
|
if((p0 & m) != 0)
|
||||||
|
return re2or(rclass(p0, p0|m), rclass((p0|m)+1, p1));
|
||||||
|
if((p1 & m) != m)
|
||||||
|
return re2or(rclass(p0, (p1&~m)-1), rclass(p1&~m, p1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
n = runetochar(xc0, &p0);
|
||||||
|
i = runetochar(xc1, &p1);
|
||||||
|
if(i != n)
|
||||||
|
error("length");
|
||||||
|
|
||||||
|
x = re2char(xc0[0], xc1[0]);
|
||||||
|
for(i=1; i<n; i++)
|
||||||
|
x = re2cat(x, re2char(xc0[i], xc1[i]));
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pcmp(const void *va, const void *vb)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
Rune *a, *b;
|
||||||
|
|
||||||
|
a = (Rune*)va;
|
||||||
|
b = (Rune*)vb;
|
||||||
|
|
||||||
|
n = a[0] - b[0];
|
||||||
|
if(n)
|
||||||
|
return n;
|
||||||
|
return a[1] - b[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert character chass into
|
||||||
|
* run-pair ranges of matches.
|
||||||
|
* this is 10646/utf specific and
|
||||||
|
* needs to be changed for some
|
||||||
|
* other input character set.
|
||||||
|
* this is the key to a fast
|
||||||
|
* regular search of characters
|
||||||
|
* by looking at sequential bytes.
|
||||||
|
*/
|
||||||
|
Re2
|
||||||
|
re2class(char *s)
|
||||||
|
{
|
||||||
|
Rune pairs[200], *p, *q, ov;
|
||||||
|
int nc;
|
||||||
|
Re2 x;
|
||||||
|
|
||||||
|
nc = 0;
|
||||||
|
if(*s == '^') {
|
||||||
|
nc = 1;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = pairs;
|
||||||
|
s += chartorune(p, s);
|
||||||
|
for(;;) {
|
||||||
|
if(*p == '\\')
|
||||||
|
s += chartorune(p, s);
|
||||||
|
if(*p == 0)
|
||||||
|
break;
|
||||||
|
p[1] = *p;
|
||||||
|
p += 2;
|
||||||
|
s += chartorune(p, s);
|
||||||
|
if(*p != '-')
|
||||||
|
continue;
|
||||||
|
s += chartorune(p, s);
|
||||||
|
if(*p == '\\')
|
||||||
|
s += chartorune(p, s);
|
||||||
|
if(*p == 0)
|
||||||
|
break;
|
||||||
|
p[-1] = *p;
|
||||||
|
s += chartorune(p, s);
|
||||||
|
}
|
||||||
|
*p = 0;
|
||||||
|
qsort(pairs, (p-pairs)/2, 2*sizeof(*pairs), pcmp);
|
||||||
|
|
||||||
|
q = pairs;
|
||||||
|
for(p=pairs+2; *p; p+=2) {
|
||||||
|
if(p[0] > p[1])
|
||||||
|
continue;
|
||||||
|
if(p[0] > q[1] || p[1] < q[0]) {
|
||||||
|
q[2] = p[0];
|
||||||
|
q[3] = p[1];
|
||||||
|
q += 2;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(p[0] < q[0])
|
||||||
|
q[0] = p[0];
|
||||||
|
if(p[1] > q[1])
|
||||||
|
q[1] = p[1];
|
||||||
|
}
|
||||||
|
q[2] = 0;
|
||||||
|
|
||||||
|
p = pairs;
|
||||||
|
if(nc) {
|
||||||
|
x = rclass(0, p[0]-1);
|
||||||
|
ov = p[1]+1;
|
||||||
|
for(p+=2; *p; p+=2) {
|
||||||
|
x = re2or(x, rclass(ov, p[0]-1));
|
||||||
|
ov = p[1]+1;
|
||||||
|
}
|
||||||
|
x = re2or(x, rclass(ov, 0xffff));
|
||||||
|
} else {
|
||||||
|
x = rclass(p[0], p[1]);
|
||||||
|
for(p+=2; *p; p+=2)
|
||||||
|
x = re2or(x, rclass(p[0], p[1]));
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
}
|
125
src/cmd/grep/grep.h
Normal file
125
src/cmd/grep/grep.h
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#include <u.h>
|
||||||
|
#include <libc.h>
|
||||||
|
#include <bio.h>
|
||||||
|
|
||||||
|
#ifndef EXTERN
|
||||||
|
#define EXTERN extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct Re Re;
|
||||||
|
typedef struct Re2 Re2;
|
||||||
|
typedef struct State State;
|
||||||
|
|
||||||
|
struct State
|
||||||
|
{
|
||||||
|
int count;
|
||||||
|
int match;
|
||||||
|
Re** re;
|
||||||
|
State* linkleft;
|
||||||
|
State* linkright;
|
||||||
|
State* next[256];
|
||||||
|
};
|
||||||
|
struct Re2
|
||||||
|
{
|
||||||
|
Re* beg;
|
||||||
|
Re* end;
|
||||||
|
};
|
||||||
|
struct Re
|
||||||
|
{
|
||||||
|
uchar type;
|
||||||
|
ushort gen;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
Re* alt; /* Talt */
|
||||||
|
Re** cases; /* case */
|
||||||
|
struct /* class */
|
||||||
|
{
|
||||||
|
Rune lo;
|
||||||
|
Rune hi;
|
||||||
|
};
|
||||||
|
Rune val; /* char */
|
||||||
|
};
|
||||||
|
Re* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
Talt = 1,
|
||||||
|
Tbegin,
|
||||||
|
Tcase,
|
||||||
|
Tclass,
|
||||||
|
Tend,
|
||||||
|
Tor,
|
||||||
|
|
||||||
|
Caselim = 7,
|
||||||
|
Nhunk = 1<<16,
|
||||||
|
Cbegin = 0x10000,
|
||||||
|
Flshcnt = (1<<9)-1,
|
||||||
|
|
||||||
|
Cflag = 1<<0,
|
||||||
|
Hflag = 1<<1,
|
||||||
|
Iflag = 1<<2,
|
||||||
|
Llflag = 1<<3,
|
||||||
|
LLflag = 1<<4,
|
||||||
|
Nflag = 1<<5,
|
||||||
|
Sflag = 1<<6,
|
||||||
|
Vflag = 1<<7,
|
||||||
|
Bflag = 1<<8
|
||||||
|
};
|
||||||
|
|
||||||
|
EXTERN union
|
||||||
|
{
|
||||||
|
char string[16*1024];
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* if a line requires multiple reads, we keep shifting
|
||||||
|
* buf down into pre and then do another read into
|
||||||
|
* buf. so you'll get the last 16-32k of the matching line.
|
||||||
|
* if pre were smaller than buf you'd get a suffix of the
|
||||||
|
* line with a hole cut out.
|
||||||
|
*/
|
||||||
|
uchar pre[16*1024]; /* to save to previous '\n' */
|
||||||
|
uchar buf[16*1024]; /* input buffer */
|
||||||
|
};
|
||||||
|
} u;
|
||||||
|
|
||||||
|
EXTERN char *filename;
|
||||||
|
EXTERN Biobuf bout;
|
||||||
|
EXTERN char flags[256];
|
||||||
|
EXTERN Re** follow;
|
||||||
|
EXTERN ushort gen;
|
||||||
|
EXTERN char* input;
|
||||||
|
EXTERN long lineno;
|
||||||
|
EXTERN int literal;
|
||||||
|
EXTERN int matched;
|
||||||
|
EXTERN long maxfollow;
|
||||||
|
EXTERN long nfollow;
|
||||||
|
EXTERN int peekc;
|
||||||
|
EXTERN Biobuf* rein;
|
||||||
|
EXTERN State* state0;
|
||||||
|
EXTERN Re2 topre;
|
||||||
|
|
||||||
|
extern Re* addcase(Re*);
|
||||||
|
extern void appendnext(Re*, Re*);
|
||||||
|
extern void error(char*);
|
||||||
|
extern int fcmp(const void*, const void*); /* (Re**, Re**) */
|
||||||
|
extern void fol1(Re*, int);
|
||||||
|
extern int getrec(void);
|
||||||
|
extern void increment(State*, int);
|
||||||
|
#define initstate grepinitstate
|
||||||
|
extern State* initstate(Re*);
|
||||||
|
extern void* mal(int);
|
||||||
|
extern void patchnext(Re*, Re*);
|
||||||
|
extern Re* ral(int);
|
||||||
|
extern Re2 re2cat(Re2, Re2);
|
||||||
|
extern Re2 re2class(char*);
|
||||||
|
extern Re2 re2or(Re2, Re2);
|
||||||
|
extern Re2 re2char(int, int);
|
||||||
|
extern Re2 re2star(Re2);
|
||||||
|
extern State* sal(int);
|
||||||
|
extern int search(char*, int);
|
||||||
|
extern void str2top(char*);
|
||||||
|
extern int yyparse(void);
|
||||||
|
extern void reprint(char*, Re*);
|
||||||
|
extern void yyerror(char*, ...);
|
226
src/cmd/grep/grep.y
Normal file
226
src/cmd/grep/grep.y
Normal file
|
@ -0,0 +1,226 @@
|
||||||
|
%{
|
||||||
|
#include "grep.h"
|
||||||
|
%}
|
||||||
|
|
||||||
|
%union
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
char* str;
|
||||||
|
Re2 re;
|
||||||
|
}
|
||||||
|
|
||||||
|
%type <re> expr prog
|
||||||
|
%type <re> expr0 expr1 expr2 expr3 expr4
|
||||||
|
%token <str> LCLASS
|
||||||
|
%token <val> LCHAR
|
||||||
|
%token LLPAREN LRPAREN LALT LSTAR LPLUS LQUES
|
||||||
|
%token LBEGIN LEND LDOT LBAD LNEWLINE
|
||||||
|
%%
|
||||||
|
|
||||||
|
prog:
|
||||||
|
expr newlines
|
||||||
|
{
|
||||||
|
$$.beg = ral(Tend);
|
||||||
|
$$.end = $$.beg;
|
||||||
|
$$ = re2cat(re2star(re2or(re2char(0x00, '\n'-1), re2char('\n'+1, 0xff))), $$);
|
||||||
|
$$ = re2cat($1, $$);
|
||||||
|
$$ = re2cat(re2star(re2char(0x00, 0xff)), $$);
|
||||||
|
topre = $$;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr:
|
||||||
|
expr0
|
||||||
|
| expr newlines expr0
|
||||||
|
{
|
||||||
|
$$ = re2or($1, $3);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr0:
|
||||||
|
expr1
|
||||||
|
| LSTAR { literal = 1; } expr1
|
||||||
|
{
|
||||||
|
$$ = $3;
|
||||||
|
}
|
||||||
|
|
||||||
|
expr1:
|
||||||
|
expr2
|
||||||
|
| expr1 LALT expr2
|
||||||
|
{
|
||||||
|
$$ = re2or($1, $3);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr2:
|
||||||
|
expr3
|
||||||
|
| expr2 expr3
|
||||||
|
{
|
||||||
|
$$ = re2cat($1, $2);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr3:
|
||||||
|
expr4
|
||||||
|
| expr3 LSTAR
|
||||||
|
{
|
||||||
|
$$ = re2star($1);
|
||||||
|
}
|
||||||
|
| expr3 LPLUS
|
||||||
|
{
|
||||||
|
$$.beg = ral(Talt);
|
||||||
|
patchnext($1.end, $$.beg);
|
||||||
|
$$.beg->alt = $1.beg;
|
||||||
|
$$.end = $$.beg;
|
||||||
|
$$.beg = $1.beg;
|
||||||
|
}
|
||||||
|
| expr3 LQUES
|
||||||
|
{
|
||||||
|
$$.beg = ral(Talt);
|
||||||
|
$$.beg->alt = $1.beg;
|
||||||
|
$$.end = $1.end;
|
||||||
|
appendnext($$.end, $$.beg);
|
||||||
|
}
|
||||||
|
|
||||||
|
expr4:
|
||||||
|
LCHAR
|
||||||
|
{
|
||||||
|
$$.beg = ral(Tclass);
|
||||||
|
$$.beg->lo = $1;
|
||||||
|
$$.beg->hi = $1;
|
||||||
|
$$.end = $$.beg;
|
||||||
|
}
|
||||||
|
| LBEGIN
|
||||||
|
{
|
||||||
|
$$.beg = ral(Tbegin);
|
||||||
|
$$.end = $$.beg;
|
||||||
|
}
|
||||||
|
| LEND
|
||||||
|
{
|
||||||
|
$$.beg = ral(Tend);
|
||||||
|
$$.end = $$.beg;
|
||||||
|
}
|
||||||
|
| LDOT
|
||||||
|
{
|
||||||
|
$$ = re2class("^\n");
|
||||||
|
}
|
||||||
|
| LCLASS
|
||||||
|
{
|
||||||
|
$$ = re2class($1);
|
||||||
|
}
|
||||||
|
| LLPAREN expr1 LRPAREN
|
||||||
|
{
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
newlines:
|
||||||
|
LNEWLINE
|
||||||
|
| newlines LNEWLINE
|
||||||
|
%%
|
||||||
|
|
||||||
|
void
|
||||||
|
yyerror(char *e, ...)
|
||||||
|
{
|
||||||
|
if(filename)
|
||||||
|
fprint(2, "grep: %s:%ld: %s\n", filename, lineno, e);
|
||||||
|
else
|
||||||
|
fprint(2, "grep: %s\n", e);
|
||||||
|
exits("syntax");
|
||||||
|
}
|
||||||
|
|
||||||
|
long
|
||||||
|
yylex(void)
|
||||||
|
{
|
||||||
|
char *q, *eq;
|
||||||
|
int c, s;
|
||||||
|
|
||||||
|
if(peekc) {
|
||||||
|
s = peekc;
|
||||||
|
peekc = 0;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
c = getrec();
|
||||||
|
if(literal) {
|
||||||
|
if(c != 0 && c != '\n') {
|
||||||
|
yylval.val = c;
|
||||||
|
return LCHAR;
|
||||||
|
}
|
||||||
|
literal = 0;
|
||||||
|
}
|
||||||
|
switch(c) {
|
||||||
|
default:
|
||||||
|
yylval.val = c;
|
||||||
|
s = LCHAR;
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
c = getrec();
|
||||||
|
yylval.val = c;
|
||||||
|
s = LCHAR;
|
||||||
|
if(c == '\n')
|
||||||
|
s = LNEWLINE;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
goto getclass;
|
||||||
|
case '(':
|
||||||
|
s = LLPAREN;
|
||||||
|
break;
|
||||||
|
case ')':
|
||||||
|
s = LRPAREN;
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
s = LALT;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
s = LSTAR;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
s = LPLUS;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
s = LQUES;
|
||||||
|
break;
|
||||||
|
case '^':
|
||||||
|
s = LBEGIN;
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
s = LEND;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
s = LDOT;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
peekc = -1;
|
||||||
|
case '\n':
|
||||||
|
s = LNEWLINE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
|
||||||
|
getclass:
|
||||||
|
q = u.string;
|
||||||
|
eq = q + nelem(u.string) - 5;
|
||||||
|
c = getrec();
|
||||||
|
if(c == '^') {
|
||||||
|
q[0] = '^';
|
||||||
|
q[1] = '\n';
|
||||||
|
q[2] = '-';
|
||||||
|
q[3] = '\n';
|
||||||
|
q += 4;
|
||||||
|
c = getrec();
|
||||||
|
}
|
||||||
|
for(;;) {
|
||||||
|
if(q >= eq)
|
||||||
|
error("class too long");
|
||||||
|
if(c == ']' || c == 0)
|
||||||
|
break;
|
||||||
|
if(c == '\\') {
|
||||||
|
*q++ = c;
|
||||||
|
c = getrec();
|
||||||
|
if(c == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*q++ = c;
|
||||||
|
c = getrec();
|
||||||
|
}
|
||||||
|
*q = 0;
|
||||||
|
if(c == 0)
|
||||||
|
return LBAD;
|
||||||
|
yylval.str = u.string;
|
||||||
|
return LCLASS;
|
||||||
|
}
|
260
src/cmd/grep/main.c
Normal file
260
src/cmd/grep/main.c
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
#define EXTERN
|
||||||
|
#include "grep.h"
|
||||||
|
|
||||||
|
char *validflags = "bchiLlnsv";
|
||||||
|
void
|
||||||
|
usage(void)
|
||||||
|
{
|
||||||
|
fprint(2, "usage: grep [-%s] [-f file] [-e expr] [file ...]\n", validflags);
|
||||||
|
exits("usage");
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, status;
|
||||||
|
|
||||||
|
ARGBEGIN {
|
||||||
|
default:
|
||||||
|
if(utfrune(validflags, ARGC()) == nil)
|
||||||
|
usage();
|
||||||
|
flags[ARGC()]++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'e':
|
||||||
|
flags['e']++;
|
||||||
|
lineno = 0;
|
||||||
|
str2top(ARGF());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
flags['f']++;
|
||||||
|
filename = ARGF();
|
||||||
|
rein = Bopen(filename, OREAD);
|
||||||
|
if(rein == 0) {
|
||||||
|
fprint(2, "grep: can't open %s: %r\n", filename);
|
||||||
|
exits("open");
|
||||||
|
}
|
||||||
|
lineno = 1;
|
||||||
|
str2top(filename);
|
||||||
|
break;
|
||||||
|
} ARGEND
|
||||||
|
|
||||||
|
if(flags['f'] == 0 && flags['e'] == 0) {
|
||||||
|
if(argc <= 0)
|
||||||
|
usage();
|
||||||
|
str2top(argv[0]);
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
follow = mal(maxfollow*sizeof(*follow));
|
||||||
|
state0 = initstate(topre.beg);
|
||||||
|
|
||||||
|
Binit(&bout, 1, OWRITE);
|
||||||
|
switch(argc) {
|
||||||
|
case 0:
|
||||||
|
status = search(0, 0);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
status = search(argv[0], 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
status = 0;
|
||||||
|
for(i=0; i<argc; i++)
|
||||||
|
status |= search(argv[i], Hflag);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(status)
|
||||||
|
exits(0);
|
||||||
|
exits("no matches");
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
search(char *file, int flag)
|
||||||
|
{
|
||||||
|
State *s, *ns;
|
||||||
|
int c, fid, eof, nl, empty;
|
||||||
|
long count, lineno, n;
|
||||||
|
uchar *elp, *lp, *bol;
|
||||||
|
|
||||||
|
if(file == 0) {
|
||||||
|
file = "stdin";
|
||||||
|
fid = 0;
|
||||||
|
flag |= Bflag;
|
||||||
|
} else
|
||||||
|
fid = open(file, OREAD);
|
||||||
|
|
||||||
|
if(fid < 0) {
|
||||||
|
fprint(2, "grep: can't open %s: %r\n", file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(flags['b'])
|
||||||
|
flag ^= Bflag; /* dont buffer output */
|
||||||
|
if(flags['c'])
|
||||||
|
flag |= Cflag; /* count */
|
||||||
|
if(flags['h'])
|
||||||
|
flag &= ~Hflag; /* do not print file name in output */
|
||||||
|
if(flags['i'])
|
||||||
|
flag |= Iflag; /* fold upper-lower */
|
||||||
|
if(flags['l'])
|
||||||
|
flag |= Llflag; /* print only name of file if any match */
|
||||||
|
if(flags['L'])
|
||||||
|
flag |= LLflag; /* print only name of file if any non match */
|
||||||
|
if(flags['n'])
|
||||||
|
flag |= Nflag; /* count only */
|
||||||
|
if(flags['s'])
|
||||||
|
flag |= Sflag; /* status only */
|
||||||
|
if(flags['v'])
|
||||||
|
flag |= Vflag; /* inverse match */
|
||||||
|
|
||||||
|
s = state0;
|
||||||
|
lineno = 0;
|
||||||
|
count = 0;
|
||||||
|
eof = 0;
|
||||||
|
empty = 1;
|
||||||
|
nl = 0;
|
||||||
|
lp = u.buf;
|
||||||
|
bol = lp;
|
||||||
|
|
||||||
|
loop0:
|
||||||
|
n = lp-bol;
|
||||||
|
if(n > sizeof(u.pre))
|
||||||
|
n = sizeof(u.pre);
|
||||||
|
memmove(u.buf-n, bol, n);
|
||||||
|
bol = u.buf-n;
|
||||||
|
n = read(fid, u.buf, sizeof(u.buf));
|
||||||
|
/* if file has no final newline, simulate one to emit matches to last line */
|
||||||
|
if(n > 0) {
|
||||||
|
empty = 0;
|
||||||
|
nl = u.buf[n-1]=='\n';
|
||||||
|
} else {
|
||||||
|
if(n < 0){
|
||||||
|
fprint(2, "grep: read error on %s: %r\n", file);
|
||||||
|
return count != 0;
|
||||||
|
}
|
||||||
|
if(!eof && !nl && !empty) {
|
||||||
|
u.buf[0] = '\n';
|
||||||
|
n = 1;
|
||||||
|
eof = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(n <= 0) {
|
||||||
|
close(fid);
|
||||||
|
if(flag & Cflag) {
|
||||||
|
if(flag & Hflag)
|
||||||
|
Bprint(&bout, "%s:", file);
|
||||||
|
Bprint(&bout, "%ld\n", count);
|
||||||
|
}
|
||||||
|
if(((flag&Llflag) && count != 0) || ((flag&LLflag) && count == 0))
|
||||||
|
Bprint(&bout, "%s\n", file);
|
||||||
|
Bflush(&bout);
|
||||||
|
return count != 0;
|
||||||
|
}
|
||||||
|
lp = u.buf;
|
||||||
|
elp = lp+n;
|
||||||
|
if(flag & Iflag)
|
||||||
|
goto loopi;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* normal character loop
|
||||||
|
*/
|
||||||
|
loop:
|
||||||
|
c = *lp;
|
||||||
|
ns = s->next[c];
|
||||||
|
if(ns == 0) {
|
||||||
|
increment(s, c);
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
// if(flags['2'])
|
||||||
|
// if(s->match)
|
||||||
|
// print("%d: %.2x**\n", s, c);
|
||||||
|
// else
|
||||||
|
// print("%d: %.2x\n", s, c);
|
||||||
|
lp++;
|
||||||
|
s = ns;
|
||||||
|
if(c == '\n') {
|
||||||
|
lineno++;
|
||||||
|
if(!!s->match == !(flag&Vflag)) {
|
||||||
|
count++;
|
||||||
|
if(flag & (Cflag|Sflag|Llflag|LLflag))
|
||||||
|
goto cont;
|
||||||
|
if(flag & Hflag)
|
||||||
|
Bprint(&bout, "%s:", file);
|
||||||
|
if(flag & Nflag)
|
||||||
|
Bprint(&bout, "%ld: ", lineno);
|
||||||
|
/* suppress extra newline at EOF unless we are labeling matches with file name */
|
||||||
|
Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
|
||||||
|
if(flag & Bflag)
|
||||||
|
Bflush(&bout);
|
||||||
|
}
|
||||||
|
if((lineno & Flshcnt) == 0)
|
||||||
|
Bflush(&bout);
|
||||||
|
cont:
|
||||||
|
bol = lp;
|
||||||
|
}
|
||||||
|
if(lp != elp)
|
||||||
|
goto loop;
|
||||||
|
goto loop0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* character loop for -i flag
|
||||||
|
* for speed
|
||||||
|
*/
|
||||||
|
loopi:
|
||||||
|
c = *lp;
|
||||||
|
if(c >= 'A' && c <= 'Z')
|
||||||
|
c += 'a'-'A';
|
||||||
|
ns = s->next[c];
|
||||||
|
if(ns == 0) {
|
||||||
|
increment(s, c);
|
||||||
|
goto loopi;
|
||||||
|
}
|
||||||
|
lp++;
|
||||||
|
s = ns;
|
||||||
|
if(c == '\n') {
|
||||||
|
lineno++;
|
||||||
|
if(!!s->match == !(flag&Vflag)) {
|
||||||
|
count++;
|
||||||
|
if(flag & (Cflag|Sflag|Llflag|LLflag))
|
||||||
|
goto conti;
|
||||||
|
if(flag & Hflag)
|
||||||
|
Bprint(&bout, "%s:", file);
|
||||||
|
if(flag & Nflag)
|
||||||
|
Bprint(&bout, "%ld: ", lineno);
|
||||||
|
/* suppress extra newline at EOF unless we are labeling matches with file name */
|
||||||
|
Bwrite(&bout, bol, lp-bol-(eof && !(flag&Hflag)));
|
||||||
|
if(flag & Bflag)
|
||||||
|
Bflush(&bout);
|
||||||
|
}
|
||||||
|
if((lineno & Flshcnt) == 0)
|
||||||
|
Bflush(&bout);
|
||||||
|
conti:
|
||||||
|
bol = lp;
|
||||||
|
}
|
||||||
|
if(lp != elp)
|
||||||
|
goto loopi;
|
||||||
|
goto loop0;
|
||||||
|
}
|
||||||
|
|
||||||
|
State*
|
||||||
|
initstate(Re *r)
|
||||||
|
{
|
||||||
|
State *s;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
addcase(r);
|
||||||
|
if(flags['1'])
|
||||||
|
reprint("r", r);
|
||||||
|
nfollow = 0;
|
||||||
|
gen++;
|
||||||
|
fol1(r, Cbegin);
|
||||||
|
follow[nfollow++] = r;
|
||||||
|
qsort(follow, nfollow, sizeof(*follow), fcmp);
|
||||||
|
|
||||||
|
s = sal(nfollow);
|
||||||
|
for(i=0; i<nfollow; i++)
|
||||||
|
s->re[i] = follow[i];
|
||||||
|
return s;
|
||||||
|
}
|
20
src/cmd/grep/mkfile
Normal file
20
src/cmd/grep/mkfile
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
PLAN9=../../..
|
||||||
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
|
# Calling this grep breaks a LOT. Like egrep on Linux.
|
||||||
|
# And probably configure.
|
||||||
|
|
||||||
|
TARG=9grep
|
||||||
|
HFILES=\
|
||||||
|
grep.h\
|
||||||
|
|
||||||
|
OFILES=\
|
||||||
|
y.tab.$O\
|
||||||
|
main.$O\
|
||||||
|
comp.$O\
|
||||||
|
sub.$O\
|
||||||
|
|
||||||
|
YFILES=grep.y\
|
||||||
|
|
||||||
|
SHORTLIB=bio 9
|
||||||
|
<$PLAN9/src/mkone
|
317
src/cmd/grep/sub.c
Normal file
317
src/cmd/grep/sub.c
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
#include "grep.h"
|
||||||
|
|
||||||
|
void*
|
||||||
|
mal(int n)
|
||||||
|
{
|
||||||
|
static char *s;
|
||||||
|
static int m = 0;
|
||||||
|
void *v;
|
||||||
|
|
||||||
|
n = (n+3) & ~3;
|
||||||
|
if(m < n) {
|
||||||
|
if(n > Nhunk) {
|
||||||
|
v = sbrk(n);
|
||||||
|
memset(v, 0, n);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
s = sbrk(Nhunk);
|
||||||
|
m = Nhunk;
|
||||||
|
}
|
||||||
|
v = s;
|
||||||
|
s += n;
|
||||||
|
m -= n;
|
||||||
|
memset(v, 0, n);
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
State*
|
||||||
|
sal(int n)
|
||||||
|
{
|
||||||
|
State *s;
|
||||||
|
|
||||||
|
s = mal(sizeof(*s));
|
||||||
|
// s->next = mal(256*sizeof(*s->next));
|
||||||
|
s->count = n;
|
||||||
|
s->re = mal(n*sizeof(*state0->re));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re*
|
||||||
|
ral(int type)
|
||||||
|
{
|
||||||
|
Re *r;
|
||||||
|
|
||||||
|
r = mal(sizeof(*r));
|
||||||
|
r->type = type;
|
||||||
|
maxfollow++;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
error(char *s)
|
||||||
|
{
|
||||||
|
fprint(2, "grep: internal error: %s\n", s);
|
||||||
|
exits(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
countor(Re *r)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
loop:
|
||||||
|
switch(r->type) {
|
||||||
|
case Tor:
|
||||||
|
n += countor(r->alt);
|
||||||
|
r = r->next;
|
||||||
|
goto loop;
|
||||||
|
case Tclass:
|
||||||
|
return n + r->hi - r->lo + 1;
|
||||||
|
}
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re*
|
||||||
|
oralloc(int t, Re *r, Re *b)
|
||||||
|
{
|
||||||
|
Re *a;
|
||||||
|
|
||||||
|
if(b == 0)
|
||||||
|
return r;
|
||||||
|
a = ral(t);
|
||||||
|
a->alt = r;
|
||||||
|
a->next = b;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
case1(Re *c, Re *r)
|
||||||
|
{
|
||||||
|
int n;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
switch(r->type) {
|
||||||
|
case Tor:
|
||||||
|
case1(c, r->alt);
|
||||||
|
r = r->next;
|
||||||
|
goto loop;
|
||||||
|
|
||||||
|
case Tclass: /* add to character */
|
||||||
|
for(n=r->lo; n<=r->hi; n++)
|
||||||
|
c->cases[n] = oralloc(Tor, r->next, c->cases[n]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* add everything unknown to next */
|
||||||
|
c->next = oralloc(Talt, r, c->next);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Re*
|
||||||
|
addcase(Re *r)
|
||||||
|
{
|
||||||
|
int i, n;
|
||||||
|
Re *a;
|
||||||
|
|
||||||
|
if(r->gen == gen)
|
||||||
|
return r;
|
||||||
|
r->gen = gen;
|
||||||
|
switch(r->type) {
|
||||||
|
default:
|
||||||
|
error("addcase");
|
||||||
|
|
||||||
|
case Tor:
|
||||||
|
n = countor(r);
|
||||||
|
if(n >= Caselim) {
|
||||||
|
a = ral(Tcase);
|
||||||
|
a->cases = mal(256*sizeof(*a->cases));
|
||||||
|
case1(a, r);
|
||||||
|
for(i=0; i<256; i++)
|
||||||
|
if(a->cases[i]) {
|
||||||
|
r = a->cases[i];
|
||||||
|
if(countor(r) < n)
|
||||||
|
a->cases[i] = addcase(r);
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
|
||||||
|
case Talt:
|
||||||
|
r->next = addcase(r->next);
|
||||||
|
r->alt = addcase(r->alt);
|
||||||
|
return r;
|
||||||
|
|
||||||
|
case Tbegin:
|
||||||
|
case Tend:
|
||||||
|
case Tclass:
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
str2top(char *p)
|
||||||
|
{
|
||||||
|
Re2 oldtop;
|
||||||
|
|
||||||
|
oldtop = topre;
|
||||||
|
input = p;
|
||||||
|
topre.beg = 0;
|
||||||
|
topre.end = 0;
|
||||||
|
yyparse();
|
||||||
|
gen++;
|
||||||
|
if(topre.beg == 0)
|
||||||
|
yyerror("syntax");
|
||||||
|
if(oldtop.beg)
|
||||||
|
topre = re2or(oldtop, topre);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
appendnext(Re *a, Re *b)
|
||||||
|
{
|
||||||
|
Re *n;
|
||||||
|
|
||||||
|
while(n = a->next)
|
||||||
|
a = n;
|
||||||
|
a->next = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
patchnext(Re *a, Re *b)
|
||||||
|
{
|
||||||
|
Re *n;
|
||||||
|
|
||||||
|
while(a) {
|
||||||
|
n = a->next;
|
||||||
|
a->next = b;
|
||||||
|
a = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
getrec(void)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
if(flags['f']) {
|
||||||
|
c = Bgetc(rein);
|
||||||
|
if(c <= 0)
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
c = *input++ & 0xff;
|
||||||
|
if(flags['i'] && c >= 'A' && c <= 'Z')
|
||||||
|
c += 'a'-'A';
|
||||||
|
if(c == '\n')
|
||||||
|
lineno++;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re2
|
||||||
|
re2cat(Re2 a, Re2 b)
|
||||||
|
{
|
||||||
|
Re2 c;
|
||||||
|
|
||||||
|
c.beg = a.beg;
|
||||||
|
c.end = b.end;
|
||||||
|
patchnext(a.end, b.beg);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re2
|
||||||
|
re2star(Re2 a)
|
||||||
|
{
|
||||||
|
Re2 c;
|
||||||
|
|
||||||
|
c.beg = ral(Talt);
|
||||||
|
c.beg->alt = a.beg;
|
||||||
|
patchnext(a.end, c.beg);
|
||||||
|
c.end = c.beg;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re2
|
||||||
|
re2or(Re2 a, Re2 b)
|
||||||
|
{
|
||||||
|
Re2 c;
|
||||||
|
|
||||||
|
c.beg = ral(Tor);
|
||||||
|
c.beg->alt = b.beg;
|
||||||
|
c.beg->next = a.beg;
|
||||||
|
c.end = b.end;
|
||||||
|
appendnext(c.end, a.end);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
Re2
|
||||||
|
re2char(int c0, int c1)
|
||||||
|
{
|
||||||
|
Re2 c;
|
||||||
|
|
||||||
|
c.beg = ral(Tclass);
|
||||||
|
c.beg->lo = c0 & 0xff;
|
||||||
|
c.beg->hi = c1 & 0xff;
|
||||||
|
c.end = c.beg;
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reprint1(Re *a)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
loop:
|
||||||
|
if(a == 0)
|
||||||
|
return;
|
||||||
|
if(a->gen == gen)
|
||||||
|
return;
|
||||||
|
a->gen = gen;
|
||||||
|
print("%p: ", a);
|
||||||
|
switch(a->type) {
|
||||||
|
default:
|
||||||
|
print("type %d\n", a->type);
|
||||||
|
error("print1 type");
|
||||||
|
|
||||||
|
case Tcase:
|
||||||
|
print("case ->%p\n", a->next);
|
||||||
|
for(i=0; i<256; i++)
|
||||||
|
if(a->cases[i]) {
|
||||||
|
for(j=i+1; j<256; j++)
|
||||||
|
if(a->cases[i] != a->cases[j])
|
||||||
|
break;
|
||||||
|
print(" [%.2x-%.2x] ->%p\n", i, j-1, a->cases[i]);
|
||||||
|
i = j-1;
|
||||||
|
}
|
||||||
|
for(i=0; i<256; i++)
|
||||||
|
reprint1(a->cases[i]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tbegin:
|
||||||
|
print("^ ->%p\n", a->next);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tend:
|
||||||
|
print("$ ->%p\n", a->next);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tclass:
|
||||||
|
print("[%.2x-%.2x] ->%p\n", a->lo, a->hi, a->next);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Tor:
|
||||||
|
case Talt:
|
||||||
|
print("| %p ->%p\n", a->alt, a->next);
|
||||||
|
reprint1(a->alt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
a = a->next;
|
||||||
|
goto loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
reprint(char *s, Re *r)
|
||||||
|
{
|
||||||
|
print("%s:\n", s);
|
||||||
|
gen++;
|
||||||
|
reprint1(r);
|
||||||
|
print("\n\n");
|
||||||
|
}
|
|
@ -3,11 +3,11 @@ PLAN9=../..
|
||||||
|
|
||||||
TARG=`ls *.c | sed 's/\.c//'`
|
TARG=`ls *.c | sed 's/\.c//'`
|
||||||
LDFLAGS=$LDFLAGS
|
LDFLAGS=$LDFLAGS
|
||||||
SHORTLIB=sec fs mux regexp9 thread bio 9
|
SHORTLIB=mach sec fs mux regexp9 thread bio 9
|
||||||
|
|
||||||
<$PLAN9/src/mkmany
|
<$PLAN9/src/mkmany
|
||||||
|
|
||||||
BUGGERED='CVS|9term|faces|factotum|htmlfmt|mk|rio|upas|vac|venti'
|
BUGGERED='CVS|faces|factotum|htmlfmt|mk|upas|vac|venti'
|
||||||
DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "^($BUGGERED)$"`
|
DIRS=`ls -l |sed -n 's/^d.* //p' |egrep -v "^($BUGGERED)$"`
|
||||||
|
|
||||||
<$PLAN9/src/mkdirs
|
<$PLAN9/src/mkdirs
|
||||||
|
|
|
@ -97,6 +97,7 @@ static Dirtab dir[NDIR] =
|
||||||
static int ndir = NQID;
|
static int ndir = NQID;
|
||||||
|
|
||||||
static int srvfd;
|
static int srvfd;
|
||||||
|
#define clock plumbclock /* SunOS name clash */
|
||||||
static int clock;
|
static int clock;
|
||||||
static Fid *fids[Nhash];
|
static Fid *fids[Nhash];
|
||||||
static QLock readlock;
|
static QLock readlock;
|
||||||
|
|
|
@ -54,9 +54,10 @@ threadmain(int argc, char *argv[])
|
||||||
error("can't initialize $user or $home: %r");
|
error("can't initialize $user or $home: %r");
|
||||||
if(plumbfile == nil){
|
if(plumbfile == nil){
|
||||||
sprint(buf, "%s/lib/plumbing", home);
|
sprint(buf, "%s/lib/plumbing", home);
|
||||||
if(access(buf, 0) < 0)
|
if(access(buf, 0) >= 0)
|
||||||
sprint(buf, "#9/plumb/initial.plumbing");
|
plumbfile = estrdup(buf);
|
||||||
plumbfile = estrdup(buf);
|
else
|
||||||
|
plumbfile = unsharp("#9/plumb/initial.plumbing");
|
||||||
}
|
}
|
||||||
|
|
||||||
fd = open(plumbfile, OREAD);
|
fd = open(plumbfile, OREAD);
|
||||||
|
|
|
@ -415,7 +415,7 @@ include(char *s)
|
||||||
fd = open(t, OREAD);
|
fd = open(t, OREAD);
|
||||||
if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){
|
if(fd<0 && t[0]!='/' && strncmp(t, "./", 2)!=0 && strncmp(t, "../", 3)!=0){
|
||||||
snprint(buf, sizeof buf, "#9/plumb/%s", t);
|
snprint(buf, sizeof buf, "#9/plumb/%s", t);
|
||||||
t = buf;
|
t = unsharp(buf);
|
||||||
fd = open(t, OREAD);
|
fd = open(t, OREAD);
|
||||||
}
|
}
|
||||||
if(fd < 0)
|
if(fd < 0)
|
||||||
|
|
|
@ -27,20 +27,10 @@ char *syssigname[]={
|
||||||
char*
|
char*
|
||||||
Rcmain(void)
|
Rcmain(void)
|
||||||
{
|
{
|
||||||
return "#9/rcmain";
|
return unsharp("#9/rcmain");
|
||||||
/*
|
|
||||||
static char buf[256];
|
|
||||||
char *root;
|
|
||||||
|
|
||||||
root = getenv("PLAN9");
|
|
||||||
if(root == nil)
|
|
||||||
root = "/usr/local/plan9";
|
|
||||||
snprint(buf, sizeof buf, "%s/rcmain", root);
|
|
||||||
return buf;
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char Fdprefix[]="#d/";
|
char Fdprefix[]="/dev/fd/";
|
||||||
void execfinit(void);
|
void execfinit(void);
|
||||||
void execbind(void);
|
void execbind(void);
|
||||||
void execmount(void);
|
void execmount(void);
|
||||||
|
|
27
src/cmd/rio/Imakefile
Normal file
27
src/cmd/rio/Imakefile
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
INCLUDES = -I$(TOP)
|
||||||
|
DEPLIBS = $(DEPXLIB)
|
||||||
|
LOCAL_LIBRARIES = $(XLIB)
|
||||||
|
DEFINES = -DSHAPE # -g3 -DDEBUG -DDEBUG_EV
|
||||||
|
SRCS = main.c event.c manage.c menu.c client.c grab.c cursor.c error.c color.c
|
||||||
|
OBJS = main.o event.o manage.o menu.o client.o grab.o cursor.o error.o color.o
|
||||||
|
HFILES = dat.h fns.h patchlevel.h
|
||||||
|
MFILES = README 9wm.man Imakefile Makefile.no-imake
|
||||||
|
|
||||||
|
ComplexProgramTarget(rio)
|
||||||
|
|
||||||
|
bun:
|
||||||
|
bundle $(MFILES) $(SRCS) $(HFILES) >bun
|
||||||
|
|
||||||
|
dist:
|
||||||
|
bundle $(MFILES) main.c event.c manage.c >bun1
|
||||||
|
bundle menu.c client.c grab.c cursor.c error.c $(HFILES) >bun2
|
||||||
|
|
||||||
|
trout: 9wm.man
|
||||||
|
troff -man 9wm.man >trout
|
||||||
|
|
||||||
|
vu: trout
|
||||||
|
xditview trout
|
||||||
|
|
||||||
|
clean::
|
||||||
|
$(RM) bun bun[12] trout core
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
|
|
||||||
unsigned long
|
unsigned long
|
||||||
colorpixel(Display *dpy, int depth, ulong rgb)
|
colorpixel(Display *dpy, int depth, unsigned long rgb)
|
||||||
{
|
{
|
||||||
int r, g, b;
|
int r, g, b;
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
#include <X11/Xatom.h>
|
#include <X11/Xatom.h>
|
||||||
|
#ifdef SHAPE
|
||||||
|
#include <X11/extensions/shape.h>
|
||||||
|
#endif
|
||||||
#include "dat.h"
|
#include "dat.h"
|
||||||
#include "fns.h"
|
#include "fns.h"
|
||||||
#include "patchlevel.h"
|
#include "patchlevel.h"
|
||||||
|
@ -70,12 +73,15 @@ main(int argc, char *argv[])
|
||||||
int i, background, do_exit, do_restart;
|
int i, background, do_exit, do_restart;
|
||||||
char *fname;
|
char *fname;
|
||||||
int shape_event;
|
int shape_event;
|
||||||
|
#ifdef SHAPE
|
||||||
|
int dummy;
|
||||||
|
#endif
|
||||||
|
|
||||||
shape_event = 0;
|
shape_event = 0;
|
||||||
myargv = argv; /* for restart */
|
myargv = argv; /* for restart */
|
||||||
|
|
||||||
do_exit = do_restart = 0;
|
do_exit = do_restart = 0;
|
||||||
background = 1;
|
background = 0;
|
||||||
font = 0;
|
font = 0;
|
||||||
fname = 0;
|
fname = 0;
|
||||||
for (i = 1; i < argc; i++)
|
for (i = 1; i < argc; i++)
|
||||||
|
@ -289,12 +295,11 @@ initscreen(ScreenInfo *s, int i, int background)
|
||||||
XSync(dpy, False);
|
XSync(dpy, False);
|
||||||
|
|
||||||
if (background) {
|
if (background) {
|
||||||
/*
|
|
||||||
XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap);
|
XSetWindowBackgroundPixmap(dpy, s->root, s->root_pixmap);
|
||||||
XClearWindow(dpy, s->root);
|
XClearWindow(dpy, s->root);
|
||||||
*/
|
} else
|
||||||
system("xsetroot -solid grey30");
|
system("xsetroot -solid grey30");
|
||||||
}
|
|
||||||
s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0x88CC88), colorpixel(dpy, s->depth, 0xE9FFE9));
|
s->menuwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 2, colorpixel(dpy, s->depth, 0x88CC88), colorpixel(dpy, s->depth, 0xE9FFE9));
|
||||||
s->sweepwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE));
|
s->sweepwin = XCreateSimpleWindow(dpy, s->root, 0, 0, 1, 1, 4, s->red, colorpixel(dpy, s->depth, 0xEEEEEE));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
PLAN9=../../..
|
||||||
<$PLAN9/src/mkhdr
|
<$PLAN9/src/mkhdr
|
||||||
|
|
||||||
OFILES=\
|
OFILES=\
|
||||||
|
@ -18,3 +19,7 @@ TARG=rio
|
||||||
LDFLAGS=-L$X11/lib -lXext -lX11
|
LDFLAGS=-L$X11/lib -lXext -lX11
|
||||||
|
|
||||||
<$PLAN9/src/mkone
|
<$PLAN9/src/mkone
|
||||||
|
|
||||||
|
CFLAGS=$CFLAGS -DSHAPE -I$X11/include
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -460,6 +460,9 @@ main(int argc, char *argv[])
|
||||||
int low;
|
int low;
|
||||||
Bits h;
|
Bits h;
|
||||||
|
|
||||||
|
codefile = unsharp(codefile);
|
||||||
|
brfile = unsharp(brfile);
|
||||||
|
|
||||||
Binit(&bin, 0, OREAD);
|
Binit(&bin, 0, OREAD);
|
||||||
Binit(&bout, 1, OWRITE);
|
Binit(&bout, 1, OWRITE);
|
||||||
for(i=0; c = "aeiouyAEIOUY"[i]; i++)
|
for(i=0; c = "aeiouyAEIOUY"[i]; i++)
|
||||||
|
|
|
@ -399,7 +399,7 @@ others(void)
|
||||||
{
|
{
|
||||||
int c, i, j;
|
int c, i, j;
|
||||||
|
|
||||||
finput = Bopen(parser, OREAD);
|
finput = Bopen(unsharp(parser), OREAD);
|
||||||
if(finput == 0)
|
if(finput == 0)
|
||||||
error("cannot open parser %s: %r", parser);
|
error("cannot open parser %s: %r", parser);
|
||||||
warray("yyr1", levprd, nprod);
|
warray("yyr1", levprd, nprod);
|
||||||
|
|
|
@ -14,7 +14,7 @@ static struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
char*
|
char*
|
||||||
_p9translate(char *old)
|
plan9translate(char *old)
|
||||||
{
|
{
|
||||||
char *new;
|
char *new;
|
||||||
int i, olen, nlen, len;
|
int i, olen, nlen, len;
|
||||||
|
@ -36,7 +36,7 @@ _p9translate(char *old)
|
||||||
len = strlen(old)+nlen-olen;
|
len = strlen(old)+nlen-olen;
|
||||||
new = malloc(len+1);
|
new = malloc(len+1);
|
||||||
if(new == nil)
|
if(new == nil)
|
||||||
return nil;
|
return "<out of memory>";
|
||||||
strcpy(new, replace[i].new);
|
strcpy(new, replace[i].new);
|
||||||
strcpy(new+nlen, old+olen);
|
strcpy(new+nlen, old+olen);
|
||||||
assert(strlen(new) == len);
|
assert(strlen(new) == len);
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
#include <u.h>
|
|
||||||
#define NOPLAN9DEFINES
|
|
||||||
#include <libc.h>
|
|
||||||
|
|
||||||
char *_p9translate(char*);
|
|
||||||
|
|
||||||
int
|
|
||||||
p9access(char *xname, int what)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
char *name;
|
|
||||||
|
|
||||||
if((name = _p9translate(xname)) == nil)
|
|
||||||
return -1;
|
|
||||||
ret = access(name, what);
|
|
||||||
if(name != xname)
|
|
||||||
free(name);
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -40,7 +40,8 @@ p9announce(char *addr, char *dir)
|
||||||
char *net;
|
char *net;
|
||||||
u32int host;
|
u32int host;
|
||||||
int port, s;
|
int port, s;
|
||||||
int n, sn;
|
int n;
|
||||||
|
socklen_t sn;
|
||||||
struct sockaddr_in sa;
|
struct sockaddr_in sa;
|
||||||
struct sockaddr_un sun;
|
struct sockaddr_un sun;
|
||||||
|
|
||||||
|
@ -72,7 +73,7 @@ p9announce(char *addr, char *dir)
|
||||||
if((s = socket(AF_INET, proto, 0)) < 0)
|
if((s = socket(AF_INET, proto, 0)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
sn = sizeof n;
|
sn = sizeof n;
|
||||||
if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (char*)&n, &sn) >= 0
|
if(port && getsockopt(s, SOL_SOCKET, SO_TYPE, (void*)&n, &sn) >= 0
|
||||||
&& n == SOCK_STREAM){
|
&& n == SOCK_STREAM){
|
||||||
n = 1;
|
n = 1;
|
||||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
|
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&n, sizeof n);
|
||||||
|
|
|
@ -3,16 +3,10 @@
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
extern char *_p9translate(char*);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
p9create(char *xpath, int mode, ulong perm)
|
p9create(char *path, int mode, ulong perm)
|
||||||
{
|
{
|
||||||
int fd, cexec, umode, rclose;
|
int fd, cexec, umode, rclose;
|
||||||
char *path;
|
|
||||||
|
|
||||||
if((path = _p9translate(xpath)) == nil)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
cexec = mode&OCEXEC;
|
cexec = mode&OCEXEC;
|
||||||
rclose = mode&ORCLOSE;
|
rclose = mode&ORCLOSE;
|
||||||
|
@ -48,7 +42,5 @@ out:
|
||||||
if(rclose)
|
if(rclose)
|
||||||
remove(path);
|
remove(path);
|
||||||
}
|
}
|
||||||
if(path != xpath)
|
|
||||||
free(path);
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ ct_numb(char *cp, int n)
|
||||||
char*
|
char*
|
||||||
asctime(Tm *t)
|
asctime(Tm *t)
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
char *ncp;
|
char *ncp;
|
||||||
static char cbuf[30];
|
static char cbuf[30];
|
||||||
|
|
||||||
|
@ -32,6 +33,12 @@ asctime(Tm *t)
|
||||||
ct_numb(cbuf+14, t->min+100);
|
ct_numb(cbuf+14, t->min+100);
|
||||||
ct_numb(cbuf+17, t->sec+100);
|
ct_numb(cbuf+17, t->sec+100);
|
||||||
ncp = t->zone;
|
ncp = t->zone;
|
||||||
|
for(i=0; i<3; i++)
|
||||||
|
if(ncp[i] == 0)
|
||||||
|
break;
|
||||||
|
for(; i<3; i++)
|
||||||
|
ncp[i] = '?';
|
||||||
|
ncp = t->zone;
|
||||||
cbuf[20] = *ncp++;
|
cbuf[20] = *ncp++;
|
||||||
cbuf[21] = *ncp++;
|
cbuf[21] = *ncp++;
|
||||||
cbuf[22] = *ncp;
|
cbuf[22] = *ncp;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <stdlib.h> /* setenv etc. */
|
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <stdlib.h> /* setenv etc. */
|
||||||
#define NOPLAN9DEFINES
|
#define NOPLAN9DEFINES
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -25,6 +24,8 @@ static Tm bigtm;
|
||||||
static void
|
static void
|
||||||
tm2Tm(struct tm *tm, Tm *bigtm)
|
tm2Tm(struct tm *tm, Tm *bigtm)
|
||||||
{
|
{
|
||||||
|
char *s;
|
||||||
|
|
||||||
memset(bigtm, 0, sizeof *bigtm);
|
memset(bigtm, 0, sizeof *bigtm);
|
||||||
bigtm->sec = tm->tm_sec;
|
bigtm->sec = tm->tm_sec;
|
||||||
bigtm->min = tm->tm_min;
|
bigtm->min = tm->tm_min;
|
||||||
|
@ -39,6 +40,13 @@ tm2Tm(struct tm *tm, Tm *bigtm)
|
||||||
#ifdef _HAVETZOFF
|
#ifdef _HAVETZOFF
|
||||||
bigtm->tzoff = tm->tm_gmtoff;
|
bigtm->tzoff = tm->tm_gmtoff;
|
||||||
#endif
|
#endif
|
||||||
|
if(bigtm->zone[0] == 0){
|
||||||
|
s = getenv("TIMEZONE");
|
||||||
|
if(s){
|
||||||
|
strecpy(bigtm->zone, bigtm->zone+4, tm->tm_zone);
|
||||||
|
free(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -18,7 +18,7 @@ mygetdents(int fd, struct dirent *buf, int n)
|
||||||
nn = getdirentries(fd, (void*)buf, n, &off);
|
nn = getdirentries(fd, (void*)buf, n, &off);
|
||||||
return nn;
|
return nn;
|
||||||
}
|
}
|
||||||
#elif defined(__APPLE__) || defined(__FreeBSD__)
|
#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||||
static int
|
static int
|
||||||
mygetdents(int fd, struct dirent *buf, int n)
|
mygetdents(int fd, struct dirent *buf, int n)
|
||||||
{
|
{
|
||||||
|
@ -171,7 +171,7 @@ dirreadall(int fd, Dir **d)
|
||||||
ts += n;
|
ts += n;
|
||||||
}
|
}
|
||||||
if(ts >= 0)
|
if(ts >= 0)
|
||||||
ts = dirpackage(fd, buf, ts, d);
|
ts = dirpackage(fd, (char*)buf, ts, d);
|
||||||
free(buf);
|
free(buf);
|
||||||
if(ts == 0 && n < 0)
|
if(ts == 0 && n < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -5,9 +5,10 @@
|
||||||
* okay.
|
* okay.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lib9.h>
|
#include <libc.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
1
src/lib9/ffork-OpenBSD.c
Normal file
1
src/lib9/ffork-OpenBSD.c
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "ffork-pthread.c"
|
|
@ -1,6 +1,5 @@
|
||||||
#include <pwd.h>
|
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <pwd.h>
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
|
||||||
char*
|
char*
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
#include <u.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <lib9.h>
|
#include <libc.h>
|
||||||
|
|
||||||
int _ntas;
|
int _ntas;
|
||||||
static int
|
static int
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
#include <u.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <lib9.h>
|
#include <libc.h>
|
||||||
|
|
||||||
void*
|
void*
|
||||||
mallocz(unsigned long n, int clr)
|
mallocz(unsigned long n, int clr)
|
||||||
|
|
|
@ -69,8 +69,6 @@ LIB9OFILES=\
|
||||||
_p9dialparse.$O\
|
_p9dialparse.$O\
|
||||||
_p9dir.$O\
|
_p9dir.$O\
|
||||||
_p9proc.$O\
|
_p9proc.$O\
|
||||||
_p9translate.$O\
|
|
||||||
access.$O\
|
|
||||||
announce.$O\
|
announce.$O\
|
||||||
argv0.$O\
|
argv0.$O\
|
||||||
atexit.$O\
|
atexit.$O\
|
||||||
|
@ -100,6 +98,7 @@ LIB9OFILES=\
|
||||||
exec.$O\
|
exec.$O\
|
||||||
fcallfmt.$O\
|
fcallfmt.$O\
|
||||||
ffork-$SYSNAME.$O\
|
ffork-$SYSNAME.$O\
|
||||||
|
get9root.$O\
|
||||||
getcallerpc-$OBJTYPE.$O\
|
getcallerpc-$OBJTYPE.$O\
|
||||||
getenv.$O\
|
getenv.$O\
|
||||||
getfields.$O\
|
getfields.$O\
|
||||||
|
@ -142,6 +141,7 @@ LIB9OFILES=\
|
||||||
u16.$O\
|
u16.$O\
|
||||||
u32.$O\
|
u32.$O\
|
||||||
u64.$O\
|
u64.$O\
|
||||||
|
unsharp.$O\
|
||||||
wait.$O\
|
wait.$O\
|
||||||
waitpid.$O\
|
waitpid.$O\
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <signal.h>
|
||||||
#define NOPLAN9DEFINES
|
#define NOPLAN9DEFINES
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
#include "9proc.h"
|
#include "9proc.h"
|
||||||
|
|
|
@ -2,12 +2,9 @@
|
||||||
#define NOPLAN9DEFINES
|
#define NOPLAN9DEFINES
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
|
||||||
extern char* _p9translate(char*);
|
|
||||||
|
|
||||||
int
|
int
|
||||||
p9open(char *xname, int mode)
|
p9open(char *name, int mode)
|
||||||
{
|
{
|
||||||
char *name;
|
|
||||||
int cexec, rclose;
|
int cexec, rclose;
|
||||||
int fd, umode;
|
int fd, umode;
|
||||||
|
|
||||||
|
@ -23,8 +20,6 @@ p9open(char *xname, int mode)
|
||||||
werrstr("mode not supported");
|
werrstr("mode not supported");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if((name = _p9translate(xname)) == nil)
|
|
||||||
return -1;
|
|
||||||
fd = open(name, umode);
|
fd = open(name, umode);
|
||||||
if(fd >= 0){
|
if(fd >= 0){
|
||||||
if(cexec)
|
if(cexec)
|
||||||
|
@ -32,7 +27,5 @@ p9open(char *xname, int mode)
|
||||||
if(rclose)
|
if(rclose)
|
||||||
remove(name);
|
remove(name);
|
||||||
}
|
}
|
||||||
if(name != xname)
|
|
||||||
free(name);
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
|
/* Could use futex(2) here instead of signals? */
|
||||||
|
|
||||||
#include "rendez-signal.c"
|
#include "rendez-signal.c"
|
||||||
|
|
1
src/lib9/rendez-OpenBSD.c
Normal file
1
src/lib9/rendez-OpenBSD.c
Normal file
|
@ -0,0 +1 @@
|
||||||
|
#include "rendez-signal.c"
|
|
@ -32,9 +32,10 @@
|
||||||
* shared memory and mutexes.
|
* shared memory and mutexes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <u.h>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <lib9.h>
|
#include <libc.h>
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#include <sys/time.h>
|
|
||||||
#include <sys/resource.h>
|
|
||||||
|
|
||||||
#include <u.h>
|
#include <u.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/resource.h>
|
||||||
#define NOPLAN9DEFINES
|
#define NOPLAN9DEFINES
|
||||||
#include <libc.h>
|
#include <libc.h>
|
||||||
|
|
||||||
|
|
|
@ -16,10 +16,12 @@ openfont(Display *d, char *name)
|
||||||
|
|
||||||
if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
|
if(fd < 0 && strncmp(name, "/lib/font/bit/", 14) == 0){
|
||||||
nambuf = smprint("#9/font/%s", name+14);
|
nambuf = smprint("#9/font/%s", name+14);
|
||||||
|
if(nambuf == nil)
|
||||||
|
return 0;
|
||||||
|
nambuf = unsharp(nambuf);
|
||||||
if(nambuf == nil)
|
if(nambuf == nil)
|
||||||
return 0;
|
return 0;
|
||||||
if((fd = open(nambuf, OREAD)) < 0){
|
if((fd = open(nambuf, OREAD)) < 0){
|
||||||
fprint(2, "failed at %s\n", nambuf);
|
|
||||||
free(nambuf);
|
free(nambuf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,26 +185,22 @@ xattach(char *label)
|
||||||
/*
|
/*
|
||||||
* Figure out underlying screen format.
|
* Figure out underlying screen format.
|
||||||
*/
|
*/
|
||||||
_x.depth = DefaultDepth(_x.display, xrootid);
|
|
||||||
if(XMatchVisualInfo(_x.display, xrootid, 16, TrueColor, &xvi)
|
if(XMatchVisualInfo(_x.display, xrootid, 16, TrueColor, &xvi)
|
||||||
|| XMatchVisualInfo(_x.display, xrootid, 16, DirectColor, &xvi)){
|
|| XMatchVisualInfo(_x.display, xrootid, 16, DirectColor, &xvi)){
|
||||||
_x.vis = xvi.visual;
|
_x.vis = xvi.visual;
|
||||||
_x.depth = 16;
|
_x.depth = 16;
|
||||||
_x.usetable = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(XMatchVisualInfo(_x.display, xrootid, 15, TrueColor, &xvi)
|
if(XMatchVisualInfo(_x.display, xrootid, 15, TrueColor, &xvi)
|
||||||
|| XMatchVisualInfo(_x.display, xrootid, 15, DirectColor, &xvi)){
|
|| XMatchVisualInfo(_x.display, xrootid, 15, DirectColor, &xvi)){
|
||||||
_x.vis = xvi.visual;
|
_x.vis = xvi.visual;
|
||||||
_x.depth = 15;
|
_x.depth = 15;
|
||||||
_x.usetable = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi)
|
if(XMatchVisualInfo(_x.display, xrootid, 24, TrueColor, &xvi)
|
||||||
|| XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){
|
|| XMatchVisualInfo(_x.display, xrootid, 24, DirectColor, &xvi)){
|
||||||
_x.vis = xvi.visual;
|
_x.vis = xvi.visual;
|
||||||
_x.depth = 24;
|
_x.depth = 24;
|
||||||
_x.usetable = 1;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
if(XMatchVisualInfo(_x.display, xrootid, 8, PseudoColor, &xvi)
|
if(XMatchVisualInfo(_x.display, xrootid, 8, PseudoColor, &xvi)
|
||||||
|
@ -218,6 +214,7 @@ xattach(char *label)
|
||||||
_x.depth = 8;
|
_x.depth = 8;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
_x.depth = DefaultDepth(_x.display, xrootid);
|
||||||
if(_x.depth != 8){
|
if(_x.depth != 8){
|
||||||
werrstr("can't understand depth %d screen", _x.depth);
|
werrstr("can't understand depth %d screen", _x.depth);
|
||||||
goto err0;
|
goto err0;
|
||||||
|
@ -225,6 +222,9 @@ xattach(char *label)
|
||||||
_x.vis = DefaultVisual(_x.display, xrootid);
|
_x.vis = DefaultVisual(_x.display, xrootid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(DefaultDepth(_x.display, xrootid) == _x.depth)
|
||||||
|
_x.usetable = 1;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* _x.depth is only the number of significant pixel bits,
|
* _x.depth is only the number of significant pixel bits,
|
||||||
* not the total number of pixel bits. We need to walk the
|
* not the total number of pixel bits. We need to walk the
|
||||||
|
@ -298,7 +298,7 @@ xattach(char *label)
|
||||||
Dx(r), /* width */
|
Dx(r), /* width */
|
||||||
Dy(r), /* height */
|
Dy(r), /* height */
|
||||||
0, /* border width */
|
0, /* border width */
|
||||||
DefaultDepthOfScreen(xscreen), /* depth */
|
_x.depth, /* depth */
|
||||||
InputOutput, /* class */
|
InputOutput, /* class */
|
||||||
_x.vis, /* visual */
|
_x.vis, /* visual */
|
||||||
/* valuemask */
|
/* valuemask */
|
||||||
|
@ -562,6 +562,18 @@ setupcmap(XWindow w)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if(_x.depth >= 24) {
|
if(_x.depth >= 24) {
|
||||||
|
/*
|
||||||
|
* This is needed for SunOS. Ask Axel Belinfante.
|
||||||
|
*/
|
||||||
|
if(_x.usetable == 0){
|
||||||
|
_x.cmap = XCreateColormap(_x.display, w, _x.vis, AllocAll);
|
||||||
|
XStoreColors(_x.display, _x.cmap, _x.map, 256);
|
||||||
|
for(i = 0; i < 256; i++){
|
||||||
|
_x.tox11[i] = i;
|
||||||
|
_x.toplan9[i] = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The pixel value returned from XGetPixel needs to
|
* The pixel value returned from XGetPixel needs to
|
||||||
* be converted to RGB so we can call rgb2cmap()
|
* be converted to RGB so we can call rgb2cmap()
|
||||||
|
@ -573,7 +585,6 @@ setupcmap(XWindow w)
|
||||||
* some displays say MSB even though they run on LSB.
|
* some displays say MSB even though they run on LSB.
|
||||||
* Besides, this is more anal.
|
* Besides, this is more anal.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
c = _x.map[19]; /* known to have different R, G, B values */
|
c = _x.map[19]; /* known to have different R, G, B values */
|
||||||
if(!XAllocColor(_x.display, _x.cmap, &c)){
|
if(!XAllocColor(_x.display, _x.cmap, &c)){
|
||||||
werrstr("XAllocColor: %r");
|
werrstr("XAllocColor: %r");
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
#include <keyboard.h>
|
#include <keyboard.h>
|
||||||
#include "x11-memdraw.h"
|
#include "x11-memdraw.h"
|
||||||
|
|
||||||
|
#undef time
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
__xtoplan9kbd(XEvent *e)
|
__xtoplan9kbd(XEvent *e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -68,7 +68,6 @@ plumbsendtofid(Fid *fid, Plumbmsg *m)
|
||||||
if(buf == nil)
|
if(buf == nil)
|
||||||
return -1;
|
return -1;
|
||||||
n = fswrite(fid, buf, n);
|
n = fswrite(fid, buf, n);
|
||||||
fprint(2, "fswrite %d\n", n);
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
49
src/libthread/asm-OpenBSD-386.s
Normal file
49
src/libthread/asm-OpenBSD-386.s
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
.globl _setlabel
|
||||||
|
.type _setlabel,@function
|
||||||
|
|
||||||
|
_setlabel:
|
||||||
|
movl 4(%esp), %eax
|
||||||
|
movl 0(%esp), %edx
|
||||||
|
movl %edx, 0(%eax)
|
||||||
|
movl %ebx, 4(%eax)
|
||||||
|
movl %esp, 8(%eax)
|
||||||
|
movl %ebp, 12(%eax)
|
||||||
|
movl %esi, 16(%eax)
|
||||||
|
movl %edi, 20(%eax)
|
||||||
|
xorl %eax, %eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
.globl _gotolabel
|
||||||
|
.type _gotolabel,@function
|
||||||
|
|
||||||
|
_gotolabel:
|
||||||
|
movl 4(%esp), %edx
|
||||||
|
movl 0(%edx), %ecx
|
||||||
|
movl 4(%edx), %ebx
|
||||||
|
movl 8(%edx), %esp
|
||||||
|
movl 12(%edx), %ebp
|
||||||
|
movl 16(%edx), %esi
|
||||||
|
movl 20(%edx), %edi
|
||||||
|
xorl %eax, %eax
|
||||||
|
incl %eax
|
||||||
|
movl %ecx, 0(%esp)
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
# .globl _xinc
|
||||||
|
# _xinc:
|
||||||
|
# movl 4(%esp), %eax
|
||||||
|
# lock incl 0(%eax)
|
||||||
|
# ret
|
||||||
|
#
|
||||||
|
# .globl _xdec
|
||||||
|
# _xdec:
|
||||||
|
# movl 4(%esp), %eax
|
||||||
|
# lock decl 0(%eax)
|
||||||
|
# jz iszero
|
||||||
|
# movl $1, %eax
|
||||||
|
# ret
|
||||||
|
# iszero:
|
||||||
|
# movl $0, %eax
|
||||||
|
# ret
|
||||||
|
#
|
|
@ -3,8 +3,8 @@
|
||||||
#include "threadimpl.h"
|
#include "threadimpl.h"
|
||||||
|
|
||||||
static void efork(int[3], int[2], char*, char**);
|
static void efork(int[3], int[2], char*, char**);
|
||||||
void
|
static void
|
||||||
threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
|
_threadexec(Channel *pidc, int fd[3], char *prog, char *args[], int freeargs)
|
||||||
{
|
{
|
||||||
int pfd[2];
|
int pfd[2];
|
||||||
int n, pid;
|
int n, pid;
|
||||||
|
@ -40,6 +40,8 @@ threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
|
||||||
efork(fd, pfd, prog, args);
|
efork(fd, pfd, prog, args);
|
||||||
_exit(0);
|
_exit(0);
|
||||||
default:
|
default:
|
||||||
|
if(freeargs)
|
||||||
|
free(args);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,10 +70,43 @@ Bad:
|
||||||
sendul(pidc, ~0);
|
sendul(pidc, ~0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
threadexec(Channel *pidc, int fd[3], char *prog, char *args[])
|
||||||
|
{
|
||||||
|
_threadexec(pidc, fd, prog, args, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The &f+1 trick doesn't work on SunOS, so we might
|
||||||
|
* as well bite the bullet and do this correctly.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
threadexecl(Channel *pidc, int fd[3], char *f, ...)
|
threadexecl(Channel *pidc, int fd[3], char *f, ...)
|
||||||
{
|
{
|
||||||
threadexec(pidc, fd, f, &f+1);
|
char **args, *s;
|
||||||
|
int n;
|
||||||
|
va_list arg;
|
||||||
|
|
||||||
|
va_start(arg, f);
|
||||||
|
for(n=0; va_arg(arg, char*) != 0; n++)
|
||||||
|
;
|
||||||
|
n++;
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
args = malloc(n*sizeof(args[0]));
|
||||||
|
if(args == nil){
|
||||||
|
if(pidc)
|
||||||
|
sendul(pidc, ~0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_start(arg, f);
|
||||||
|
for(n=0; (s=va_arg(arg, char*)) != 0; n++)
|
||||||
|
args[n] = s;
|
||||||
|
args[n] = 0;
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
_threadexec(pidc, fd, f, args, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
typedef struct Label Label;
|
typedef struct Label Label;
|
||||||
#define LABELDPC 0
|
#define LABELDPC 0
|
||||||
|
|
||||||
#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__))
|
#if defined (__i386__) && (defined(__FreeBSD__) || defined(__linux__) || defined(__OpenBSD__))
|
||||||
struct Label
|
struct Label
|
||||||
{
|
{
|
||||||
ulong pc;
|
ulong pc;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<mkhdr
|
<mkhdr
|
||||||
|
|
||||||
BUGGERED='9p|html|httpd|ip|venti'
|
BUGGERED='9p|fmt|html|httpd|ip|utf|venti'
|
||||||
LIBDIRS=`ls -ld lib* | sed -n 's/^d.* //p' |egrep -v "^lib($BUGGERED)$"`
|
LIBDIRS=`ls -ld lib* | sed -n 's/^d.* //p' |egrep -v "^lib($BUGGERED)$"`
|
||||||
|
|
||||||
DIRS=\
|
DIRS=\
|
||||||
|
|
Loading…
Reference in a new issue