819 Commits

Author SHA1 Message Date
Ben Gras
7be1d47d24 don't always copy for i/o instructions. 2009-06-08 15:59:29 +00:00
Ben Gras
3765538c76 merging in memory freeer. 2009-06-08 15:31:45 +00:00
Ben Gras
01732ffb5e quick hack (sorry) for making *sdevio* work to other
processes than the caller..

also disable kernel sanity checks
2009-06-08 14:33:15 +00:00
Ben Gras
8a0ab8630c rebase from trunk 2009-06-08 12:25:24 +00:00
Ben Gras
a236a39e33 .. 2009-06-08 07:33:42 +00:00
Ben Gras
a2358ad071 2009-06-08 06:35:18 +00:00
Ben Gras
de1b5e0076 cleanup, sanity checking 2009-06-08 06:08:11 +00:00
Ben Gras
782133423e allow empty senda 2009-06-08 04:39:26 +00:00
Ben Gras
9e72241374 minor cleanup 2009-06-08 04:30:16 +00:00
Ben Gras
ac86f5bb49 keep some processes mapped in always; direct message copying
where possible (no buffering); no more explicit vm checkranges
in kernel; new allocator for vm using avl tree without needing
remapping
2009-06-08 04:02:22 +00:00
Ben Gras
e2a7535c55 minor cleanup 2009-06-07 16:25:37 +00:00
Ben Gras
0702c826a2 pde cache check works
no more silly vm checkranges
2009-06-07 15:55:44 +00:00
Ben Gras
4dae6c4bbc my state.
trying to get some memory optimisation (less pagetable reloading,
less tlb purging) features working smoothly.

to be documented when committing to trunk :)
2009-06-06 23:27:10 +00:00
Ben Gras
9d56ac3fc9 only switch pagetable if necessary and it's different for copying messages 2009-06-03 15:28:13 +00:00
Ben Gras
37cd6bc06c move field offset from vir region from phys_block to phys_region, so
the same blocks of physical memory can be mapped in in different offsets
within regions.
2009-06-03 12:18:13 +00:00
Ben Gras
eb2959a560 state 2009-06-03 11:22:49 +00:00
Ben Gras
f16eb59bbf further messing with page fault handling 2009-05-29 18:47:31 +00:00
Ben Gras
85881e9995 no vm_setbuf any more (kernel doesn't create its page table any more),
no relocking field (locks not checked)
2009-05-28 14:23:38 +00:00
Ben Gras
9b73964f6d beng work in progress, to be explained in a future commit message :). 2009-05-28 13:47:20 +00:00
Ben Gras
78e5d6d4eb unused confusing malloc/free functions in sysutil 2009-05-28 12:14:37 +00:00
Ben Gras
6579bb3656 copy of beng's working copy 2009-05-20 16:54:58 +00:00
David van Moolenbroek
00a2463d71 update readlink(2) manpage accordingly 2009-05-20 11:49:10 +00:00
David van Moolenbroek
9797d17d54 move symlink type check for readlink() into VFS, and return the right POSIX error 2009-05-20 09:46:06 +00:00
David van Moolenbroek
50b77e3529 VFS consistency: use I_PIPE/NO_PIPE when checking v_pipe 2009-05-19 14:34:44 +00:00
Ben Gras
8ee3d26722 don't include /usr/src changes in packages. 2009-05-19 10:55:15 +00:00
Ben Gras
fe39483dc9 4MB mask 2009-05-18 15:56:13 +00:00
Ben Gras
f86da99e67 map in kernel in 4MB, global-bit-set 'pages' if hardware
supports it. helps performance.

broken use of region data structure for kernel mapping to be fixed.
2009-05-18 15:34:42 +00:00
David van Moolenbroek
f76d75a5ec Various VFS and MFS fixes to improve correctness, consistency and
POSIX compliance.

VFS changes:
* truncate() on a file system mounted read-only no longer panics MFS.
* ftruncate() and fcntl(F_FREESP) now check for write permission on
  the file descriptor instead of the file, write().
* utime(), chown() and fchown() now check for file system read-only
  status.

MFS changes:
* link() and rename() no longer return the internal EENTERMOUNT and
  ELEAVEMOUNT errors to the application as part of a check on the
  source path.
* rename() now treats EENTERMOUNT from the destination path check as
  an error, preventing file system corruption from renaming a normal
  directory to an existing mountpoint directory.
* mountpoints (mounted-on dirs) are hidden better during lookups:
  - if a lookup starts from a mountpoint, the first component has to
    be ".." (anything else being a VFS-FS protocol violation).
  - in that case, the permissions of the mountpoint are not checked.
  - in all other cases, visiting a mountpoint always results in
    EENTERMOUNT.
* a lookup on ".." from a mount root or chroot(2) root no longer
  succeeds if the caller does not have search permission on that
  directory.
* POSIX: getdents() now updates directory access times.
* POSIX: readlink() now returns partial results instead of ERANGE.

Miscellaneous changes:
* semaphore file handling bug (leading to hangs) fixed in test 32.

The VFS changes should now put the burden of checking for read-only
status of file systems entirely on VFS, and limit the access
permission checks that file systems have to perform, to checking
search permission on directories during lookups. From this point on,
any deviation from that spceification should be considered a bug.
Note that for legacy reasons, the root partition is assumed to be
mounted read-write.
2009-05-18 11:27:12 +00:00
Ben Gras
bdab3c4cfb Library call for cpu features; make kernel and vm use this to query cpu
features (specifically: 4MB pages and TLB global bit).  Only enable
these features in CR4 if available. 4MB pages to be used in the near
future.
2009-05-15 17:07:36 +00:00
Ben Gras
d0b6e76bfb correct the revision variable used in /etc/version 2009-05-15 13:02:23 +00:00
Arun Thomas
d749b3b965 -Remove qemu_pci boot variable. Useres no longer need to set qemu_pci when
booting MINIX under QEMU/KVM.
-Kept the diagnostic message, however.
2009-05-14 19:07:37 +00:00
Ben Gras
143422fa0a C CPUID interface. 2009-05-14 15:55:28 +00:00
Arun Thomas
db4faccbf9 -Installation info is on the wiki now, so remove setup guides and update
README.
-Remove obsolete FAT partitioning utility.
-Update startup banner.
2009-05-14 15:54:02 +00:00
David van Moolenbroek
c2aef85eda Clear trace bit for child on fork.
Without this, a forking single-stepped process will have its child
die from a TRAP signal right away.
2009-05-13 21:58:10 +00:00
David van Moolenbroek
fe8c612aa4 support in 'mount' for specifying file system type and options 2009-05-13 15:39:44 +00:00
David van Moolenbroek
3affa4c796 'service' null pointer dereference fix 2009-05-12 16:52:00 +00:00
Ben Gras
dd56aa321f to let tty run with its own page table (instead of with the kernel identity
map table), make it map in video memory.

sadly, this breaks tty in non-paged mode.

happily, this simplifies the code by throwing out the messing
around with segments, and throws out vidcopy.s.
2009-05-12 12:43:18 +00:00
Ben Gras
909c1bb8a7 don't bother with unmapping physical memory in non-sanitycheck mode. 2009-05-12 11:51:53 +00:00
Ben Gras
581e68433a basic sparepage optimisation
some simplification of linear/virtual address translation
(less hardcoding and more use of arch_*2* functions)
2009-05-12 11:38:29 +00:00
Ben Gras
f9e81cb57b remove bogus arch_map2vir calls 2009-05-12 11:36:15 +00:00
Ben Gras
6fad23f500 don't call this function with a bogus addr (done by region.c print code) 2009-05-12 11:35:49 +00:00
Ben Gras
e3ca89c0be more sanity checking. sanity checking disabled by default.
give every process a full pagetable by default now.

first step to disabling kernel page table code (processes
might not have page tables -> no address translation).
2009-05-12 11:35:01 +00:00
Ben Gras
ebe050dbe2 large page size constant. 2009-05-12 09:23:27 +00:00
Ben Gras
d2caeb6146 start all processes, including VM, in VM_PROCSTART in linear address space,
to make space for kernel to be able to map in things below there.
2009-05-11 19:11:37 +00:00
Ben Gras
ade4c03b73 Don't build arch objs more than once. 2009-05-11 19:05:45 +00:00
Ben Gras
7c88767f75 remove debug msg 2009-05-11 11:57:20 +00:00
David van Moolenbroek
9a01c828c8 VFS-FS error codes: better safe than sorry 2009-05-11 11:30:04 +00:00
David van Moolenbroek
0ac1aaccca Limited support for nested FS->VFS requests during VFS->FS call.
- Changed VFS-FS protocol to only store OK or negative error code in
  m_type field of reply messages.
- Changed VFS to treat nonzero positive replies from FS as requests.
- Added backwards compatibility to VFS and MFS.
No protection of global data structures is provided in VFS, so many
VFS calls cannot be made safely by FS servers during many FS calls.
Use with caution (or, preferably, not at all).
2009-05-11 10:02:28 +00:00
David van Moolenbroek
dcfaf50f79 wrong field index in at_wini env_parse call 2009-05-10 16:58:23 +00:00
David van Moolenbroek
a2485b346c potential buffer overruns in env_* routines 2009-05-10 16:54:37 +00:00
David van Moolenbroek
e08b38a5c4 regression fix: vfs lookup passes incorrect chroot information after crossing mountpoints 2009-05-09 17:53:22 +00:00
David van Moolenbroek
021808b12a fix for commands that try to include mfs constants from vfs 2009-05-08 20:37:06 +00:00
David van Moolenbroek
293be6b80b quick cleanup of old mfs cruft from vfs 2009-05-08 14:12:41 +00:00
Ben Gras
dc1238b7b9 make unpause() decrease susp_count, as it shouldn't be decreased
if the process was REVIVING. (susp_count doesn't count those
 processes.) this together with dev_io SELECT suspend side effect
 for asynch. character devices solves the hanging pipe bug. or
 at last vastly improves it.

 added sanity checks, turned off by default.

 made the {NOT_,}{SUSPENDING,REVIVING} constants weirder to
 help sanity checking.
2009-05-08 13:56:41 +00:00
David van Moolenbroek
113b1ec5f3 remove unused global variable from vfs 2009-05-08 13:54:01 +00:00
Ben Gras
ece26e2731 don't suspend the process as a side-effect if
device returns SUSPEND if it's select; select already
does this.
2009-05-08 13:50:29 +00:00
David van Moolenbroek
2a48c4ad48 Reenable RS table dump from IS (Shift+F6) 2009-05-08 12:38:14 +00:00
David van Moolenbroek
e9e347f5b6 Fix for large transfer operations not advancing buffer address
offset when DMA transfer unit is smaller than given buffer size.
Bug tracker item #82.
2009-05-08 12:29:57 +00:00
David van Moolenbroek
4af032bbfe Kernel interrupt hook management fixes:
- properly assign unique hook IDs
- after hook removal, remove hook-specific interrupt disable flag
2009-05-07 14:52:07 +00:00
Ben Gras
a38287067a disable scary looking debug messages. 2009-05-07 09:58:16 +00:00
Ben Gras
746e138036 turn off scary looking debug messages. 2009-05-07 09:57:43 +00:00
Ben Gras
8b72765e39 ignore errors of pipe read (can happen with shutdown now,
now that all fd's are closed neatly in vfs), change messaging
in unexpected restarts
2009-05-06 15:38:32 +00:00
Ben Gras
fd7ef243e4 cleanup of vfs shutdown logic; makes clean unmounts easier (but
needs checking if fp_wd or fp_rd is NULL before use)
2009-04-29 16:59:18 +00:00
Ben Gras
b7e23b70e8 - delete unused .h files
- slight code cleanup
 - neater exit procedure: exit when unmount
   message received and kill signal (from RS 'down' or
   reboot/shutdown) received (speed up unmount, but don't
   confuse VFS by exiting before/during unmount msg)
2009-04-27 16:13:51 +00:00
Ben Gras
bb23344283 spurious debug 2009-04-27 16:11:38 +00:00
Ben Gras
02f047d008 lose -s flag for umount. 2009-04-27 14:23:57 +00:00
Ben Gras
a12113e476 process restarts are pretty rare/serious. 2009-04-27 14:07:47 +00:00
Ben Gras
4593eaec24 minor fixes to install script - allow 8kB blocksize (necessary for
large filesystems)
2009-04-27 12:59:49 +00:00
Ben Gras
60e7602aad When we receive a PROC_EVENT message from PM, exit nicely; avoids
annoying graceful RS timeout on unmount.
2009-04-27 12:02:31 +00:00
Ben Gras
e5209d51f1 bad dma fallback to pio mode 2009-04-27 11:53:11 +00:00
Ben Gras
3b3e3b36c2 some more vm bits. 2009-04-23 15:21:03 +00:00
Ben Gras
ef8a741301 set global flag for kernel pages, so tlb entries for kernel aren't thrown
away on cr3 reload. minor optimization.
2009-04-23 15:11:16 +00:00
Arun Thomas
e9e1ae1cfc Move queue.h to include/sys so that it can be used elsewhere. Pull in
FreeBSD's r179210 queue.h.
2009-04-22 20:02:39 +00:00
Arun Thomas
f149733e16 Disable IOMMU warnings. 2009-04-22 16:53:46 +00:00
Arun Thomas
3b37103fa3 Make the rtl8139 and orinoco drivers handle the system shutdown case
like other drivers. Also, some minor cleanups.
2009-04-22 12:42:37 +00:00
Ben Gras
2dd02cc560 mark pages whose refcount were >1 and drop to 1 and are
read/write writable in the pagetable right away instead of waiting for
a pagefault. minor optimization.

some a sanity check of SLAB-allocated pointers.

vm gets its own _exit and __exit like PM, so the stock (library) panic works.
2009-04-22 12:39:29 +00:00
Ben Gras
e0f3a5acf1 - enable ipc warnings by default
- ipc checking code in kernel didn't properly catch the
   sendrec() to self case; added special case check
 - triggered by PM using stock panic() - needs its own _exit()

reported by Joren l'Ami.
2009-04-17 13:46:37 +00:00
Ben Gras
e5717f7aef clarify not found error message a bit. 2009-04-14 14:16:24 +00:00
Ben Gras
4cd6875d05 don't flush output for SIGWINCH. found by Joren l'Ami. 2009-04-06 09:39:42 +00:00
Ben Gras
65a9f0253b unnecessary debugging message 2009-04-02 16:43:35 +00:00
Ben Gras
9647fbc94e moved type and constants for random data to include file;
added consistency check in random; added source of randomness
internal to random using timing; only retrieve random bins that are full.
2009-04-02 15:24:44 +00:00
Ben Gras
51596bc608 print who the message is from. 2009-04-02 11:56:50 +00:00
Ben Gras
73ee8b8b99 don't make susp_count negative. 2009-04-02 11:44:26 +00:00
Ben Gras
b560a36b20 trace fix contributed by Joren l'Ami 2009-04-02 11:38:23 +00:00
Ben Gras
dc9a1bc30c increment nph when printing physical regions; suggested by Guanqun Lu 2009-03-31 14:26:24 +00:00
Ben Gras
45d54cf1b0 change DmaMode checks from DEV_WRITE to DEV_WRITE_S 2009-03-31 14:23:33 +00:00
Arun Thomas
9e7837f63c Tweak 64-bit integer type declarations; Fixes GCC sysutil build
breakage.
2009-03-30 17:07:39 +00:00
Ben Gras
3bb80322d9 suppress more mostly-harmless messages. 2009-03-26 16:11:27 +00:00
Ben Gras
2d1c884e35 suppress these noisy, alarming messages. 2009-03-26 15:56:08 +00:00
Ben Gras
cd2d85c13d no 'small minix' option 2009-03-26 15:54:09 +00:00
Ben Gras
f56316a168 don't need to explicitly enable lance any more. 2009-03-26 15:23:07 +00:00
Ben Gras
cf8c4cc851 ignore linmem.
don't disable the driver by default.
2009-03-26 15:22:08 +00:00
Ben Gras
4e2291fff2 SizeMB isn't used any more. 2009-03-26 13:19:14 +00:00
Ben Gras
ec50fa00c7 don't execute hlt in real mode.
workaround for getting minix under qemu kvm.
Ameya, ape800 at few.vu.nl.
2009-03-24 16:08:10 +00:00
Ben Gras
fc11209417 more inodes than default for /usr on cd. 2009-03-24 15:41:51 +00:00
Ben Gras
46d28c6ffb workaround for qemu writing the configuration byte on the AUX port pre-0.10. 2009-03-24 15:41:18 +00:00
Ben Gras
d8d63f0e07 make USRMB settable 2009-03-19 14:14:57 +00:00
Ben Gras
e5079dfc02 multiple ram disks; also make release process use this
so temporary partitions aren't needed any more.
2009-03-19 13:48:19 +00:00
Arun Thomas
347fa61675 Increase ARG_MAX 2009-03-17 07:38:35 +00:00
Arun Thomas
5eb353ebbc Update setup's NIC selection dialog 2009-03-06 17:45:22 +00:00
Arun Thomas
7ce582c783 Define 64 bit integer types when compiling with GCC 2009-03-06 16:56:46 +00:00
Ben Gras
8af5f877bc 2009-03-04 17:44:34 +00:00
Ben Gras
3f6e061948 fix error check 2009-03-04 17:38:27 +00:00
Ben Gras
a742aed5ad only assign value if request went ok. 2009-02-19 17:14:36 +00:00
Ben Gras
cd37a0299c Check for firstdatazone overflow. 2009-02-17 13:01:25 +00:00
Ben Gras
733d6c1ef6 help debugging cause of these sometimes odd calls. 2009-02-17 12:09:59 +00:00
Ben Gras
570b9cd753 Checking wrong inode pointer for refcount in mount (!) 2009-02-17 09:50:02 +00:00
Ben Gras
379be7f0fb A serial ata pci card we have. 2009-02-16 13:20:10 +00:00
Ben Gras
1f3dd53283 We don't install the bzip2 manual, much less four copies of it, and
it's quite big.
2009-02-16 10:01:22 +00:00
Ben Gras
01f1132eac let at_wini see ata raid controllers 2009-02-12 12:28:28 +00:00
Ben Gras
59e972f074 let drivers allocate memory at 64k physical boundary. 2009-02-12 12:26:08 +00:00
Ben Gras
6ac0338584 Don't declare the cprof buf if CPROFILE isn't on. 2009-02-06 16:31:28 +00:00
Ben Gras
b696823379 stingy stack. 2009-02-06 16:29:00 +00:00
Ben Gras
95ff97d4fb readclock easily runs out of stack with so little of it. 2009-02-06 16:28:35 +00:00
Ben Gras
eafd4730ea check for devices that would need more blocks than 32
bits allow..
2009-02-05 16:30:20 +00:00
Ben Gras
6e86e6706d fix compiler warning; missing memory range check 2009-02-05 13:00:03 +00:00
Ben Gras
bb18be5d06 simplified the code a little, corrected some hasty statements. 2009-02-04 17:30:01 +00:00
Ben Gras
6a0e8e3b80 Added a separate keymap for escaped scancodes. This makes the code
a little cleaner (escaped scancodes are less of a special case) and
lets us be completely flexible when assigning meaning to them.

Future: a tool and ioctl to load the escaped keymap.
2009-02-04 17:04:16 +00:00
Ben Gras
ba4687e519 the escaped keymap is usually the same as the original. 2009-02-04 16:55:30 +00:00
Ben Gras
113932905f disable interrupts if necessary in kernel debug code to dump all process
stacks.
2009-01-29 15:13:54 +00:00
Ben Gras
80f5eea8b8 If serial debugging in the boot monitor / kernel is enabled, don't touch
the serial line in use for it (mostly so that input isn't eaten by tty).
2009-01-29 15:06:40 +00:00
Ben Gras
d0a2e6b2f4 use library panic, doesn't need its own any more. 2009-01-29 14:41:44 +00:00
Ben Gras
c628f24bc2 moved stacktrace to sysctl, as vmctl is very privileged so can't
be used outside VM. IS code cleanup. added stacktrace feature to IS.
2009-01-27 12:54:33 +00:00
Ben Gras
3cc092ff06 . new kernel call sysctl for generic unprivileged system operations;
now used for printing diagnostic messages through the kernel message
   buffer. this lets processes print diagnostics without sending messages
   to tty and log directly, simplifying the message protocol a lot and
   reducing difficulties with deadlocks and other situations in which
   diagnostics are blackholed (e.g. grants don't work). this makes
   DIAGNOSTICS(_S), ASYN_DIAGNOSTICS and DIAG_REPL obsolete, although tty
   and log still accept the codes for 'old' binaries. This also simplifies
   diagnostics in several servers and drivers - only tty needs its own
   kputc() now.
 . simplifications in vfs, and some effort to get the vnode references
   right (consistent) even during shutdown. m_mounted_on is now NULL
   for root filesystems (!) (the original and new root), a less awkward
   special case than 'm_mounted_on == m_root_node'. root now has exactly
   one reference, to root, if no files are open, just like all other
   filesystems. m_driver_e is unused.
2009-01-26 17:43:59 +00:00
Ben Gras
4984a86f32 don't hang on disappearing filesystem. 2009-01-26 13:02:41 +00:00
Ben Gras
b784e88026 prototype 2009-01-22 17:09:45 +00:00
Ben Gras
539192f4c3 must be unsigned for base+limit check to to work 2009-01-22 13:05:20 +00:00
Ben Gras
36c12c1251 package list sanity check 2009-01-20 15:49:42 +00:00
Ben Gras
0f41416100 minor cleanup, extra check 2009-01-20 15:47:00 +00:00
Ben Gras
723a756c14 reduce kernel buffer size. 2009-01-20 13:57:24 +00:00
Ben Gras
86e7e4828e sanity check function 2009-01-20 13:43:18 +00:00
Ben Gras
45ec30f6af mostly harmless sanity checks. 2009-01-20 13:43:00 +00:00
Ben Gras
6a267baeb8 simplification suggested by Mark Farnsworth 2009-01-15 14:42:40 +00:00
Ben Gras
36909196cf make bootinfo valid immediately 2009-01-14 08:56:20 +00:00
Ben Gras
4f08002c2c RS needs a bit more memory 2009-01-14 08:55:48 +00:00
Ben Gras
ef2867de41 don't print if we're already printing to serial. 2009-01-14 08:54:17 +00:00
Ben Gras
b4934f0e12 debug twiddle. 2009-01-14 08:52:50 +00:00
Ben Gras
b450c33377 sometime this will be a new release. 2009-01-14 08:38:37 +00:00
Ben Gras
5cbcc11ed3 compile fix for new lock timings 2009-01-12 22:14:43 +00:00
Ben Gras
3ca00a926c don't produce kernel output if serial debug is on. 2009-01-11 23:47:03 +00:00
Ben Gras
d5f978411e use #include name for servarname 2009-01-11 23:45:29 +00:00
Ben Gras
037f39767c debug msg 2009-01-09 21:47:04 +00:00
Ben Gras
cd54beeb30 cprofile not conditional 2009-01-09 21:45:27 +00:00
Ben Gras
c27008fbcc cprofile not conditional 2009-01-09 21:44:52 +00:00
Ben Gras
e190ff9f84 cprofile always on 2009-01-09 21:42:36 +00:00
Ben Gras
b82588848d cprofile always on; data type and definitions to include file 2009-01-09 21:40:29 +00:00
Ben Gras
628ed99101 CPROFILE wants this 2009-01-09 21:11:23 +00:00
Ben Gras
22d9444773 don't always time that 2009-01-09 20:58:35 +00:00
Ben Gras
7d48584659 profbuf syscall 2009-01-09 17:47:38 +00:00
Ben Gras
ad87da99d3 bigger ramdisk for bigger binaries 2009-01-09 17:47:18 +00:00
Ben Gras
7606dc5f1f profiling reminder 2009-01-09 16:44:47 +00:00
Ben Gras
ad03a650e6 timing library from kernel into library 2009-01-09 16:39:31 +00:00
Ben Gras
7740d0379c no longer in kernel 2009-01-09 16:35:25 +00:00
Ben Gras
128a0508c0 timing measurement code out of kernel and into library
(so other components can use it too)
2009-01-09 16:15:15 +00:00
Ben Gras
54b3f50b05 actually build and install zoneinfo. 2008-12-21 04:33:50 +00:00
Ben Gras
1943df25dd forget about bad block testing. 2008-12-21 04:26:41 +00:00
Ben Gras
523fdf2729 stopgap measure against elvis going nuts when files that are too large
are opened.
2008-12-21 04:01:01 +00:00
Ben Gras
0579810535 don't ignore the fact that scancodes are escaped.
if not understood explicitly, print diagnostic and 
ignore scancode.
2008-12-21 03:53:25 +00:00
Ben Gras
23a158b361 don't check senda() buffer if size is 0. 2008-12-21 03:46:42 +00:00
Ben Gras
203eb54a4c make space for first code and data pages if so configured. 2008-12-19 15:46:29 +00:00
Ben Gras
d2757d4b73 debug buffer slightly usabler. 2008-12-19 15:19:42 +00:00
Ben Gras
866a4a667e phys addr arg of 0 must be possible for pt_writemap too (instead of meaning
unmap).
2008-12-19 13:29:12 +00:00
Ben Gras
b740ff055f if serial output is enabled in the boot monitor, on the first serial line,
enable serial debug output in the kernel too.
2008-12-19 13:21:42 +00:00
Ben Gras
7fdc181d5f /boot/boot install helper script. 2008-12-19 12:52:45 +00:00
Ben Gras
8072ef5509 oops, shouldn't be on in svn. 2008-12-18 17:42:29 +00:00
Ben Gras
3121eec6bd . map text (kernel's and processes') in readonly
. map kernel in non-user
 . don't map in first pages of kernel code and data
   if possible

these first pages could actually be freed but as the
kernel isn't allowed to touch them either we can't reuse
them until VM has totally taken over page table management
and kernel doesn't rely on identity mapping any more.
2008-12-18 15:35:22 +00:00
Ben Gras
f0000078c3 make kernel leave a page-sized gap in its code and data to not be
mapped in if so configured.
2008-12-18 14:30:55 +00:00
Ben Gras
834d9d34e8 Initialize deferred field. This seems to fix a hanging select() bug. 2008-12-17 14:20:08 +00:00
Ben Gras
2528a06954 bugfix for lance. works in vmware now. 2008-12-17 01:20:15 +00:00
Ben Gras
34d5401ed4 put put_vnode() back where it belongs! 2008-12-16 16:11:24 +00:00
Ben Gras
46ecfa2b5c syslib function for VMCTL_STACKTRACE 2008-12-16 14:42:32 +00:00
Ben Gras
710f44c4b8 added code for debugging pagefaults 2008-12-16 14:33:53 +00:00
Ben Gras
4be5b6f437 2008-12-16 14:32:56 +00:00
Ben Gras
a306c63e0b 2008-12-15 15:16:26 +00:00
Ben Gras
8beff61807 get fproc table. don't print size as that doesn't say much in VM mode.
this restores ps.
2008-12-15 13:05:52 +00:00
Ben Gras
e4e3995fb0 don't force vm to print to serial; don't kill processes when they
have 'bad' memory ranges (as it's the requestor's fault)
2008-12-11 17:36:33 +00:00
Ben Gras
ef812af5a6 use VM functions to allocate ramdisk on demand. some unification in code. 2008-12-11 17:33:13 +00:00
Ben Gras
73e3431dfd DEV_BOOT is obsolete. 2008-12-11 16:50:11 +00:00
Ben Gras
0cd26cd1c0 DEV_BOOT is obsolete. 2008-12-11 16:50:01 +00:00
Ben Gras
6009642110 for compatability with older images. 2008-12-11 15:50:33 +00:00
Ben Gras
5db1a042c2 stacktrace feature. 2008-12-11 15:33:43 +00:00
Ben Gras
6300c26921 prototype fix 2008-12-11 15:02:44 +00:00
Ben Gras
fe3e0181d4 straggler. 2008-12-11 14:55:06 +00:00
Ben Gras
70f1f28439 dynamic HZ, library stacktrace 2008-12-11 14:54:42 +00:00
Ben Gras
b6b361a474 rc script needs to open its own stdin, stdout and stderr 2008-12-11 14:50:56 +00:00
Ben Gras
011de3ac49 everyone needs GETINFO for HZ 2008-12-11 14:50:28 +00:00
Ben Gras
2024bf0bcf . no more HZ
. let user processes query HZ
 . no more custom panic()
2008-12-11 14:49:17 +00:00
Ben Gras
ccf70aa989 system_hz replaces HZ 2008-12-11 14:48:05 +00:00
Ben Gras
7d674f4b8e no more HZ; less debugging statements 2008-12-11 14:47:48 +00:00
Ben Gras
b9a0d46ea9 debug out 2008-12-11 14:46:46 +00:00
Ben Gras
3287b7f7d8 don't hang old binaries 2008-12-11 14:45:49 +00:00
Ben Gras
5e1bb6eb63 added some code to debug why filesystems won't unmount 2008-12-11 14:45:31 +00:00
Ben Gras
e96f86ed8c throw out debugging code. 2008-12-11 14:44:10 +00:00
Ben Gras
eeba8ef01f No more HZ. 2008-12-11 14:43:53 +00:00
Ben Gras
e9f0c576a3 Open stdin, stdout and stderr only after /etc/rc has executed. (/etc/rc
executes it itself.) This avoids keeping /dev nodes on the temporary
root filesystem (initial mfs) in use unnecessarily.
2008-12-11 14:43:25 +00:00
Ben Gras
1d8aed840c . no more HZ, but use sys_hz() to get that value
. memory maps in physical memory (for /dev/mem) with new vm interface
 . pci complete_bars() seems to be buggy behaviour sometimes
 . startup script opens its own stdout, stderr and stdin so init doesn't
   have to do it
2008-12-11 14:42:23 +00:00
Ben Gras
6cfe4bdd2d slight args change 2008-12-11 14:37:42 +00:00
Ben Gras
991000dd70 dynamic HZ 2008-12-11 14:37:18 +00:00
Ben Gras
eae27c899a move senda to sep. file 2008-12-11 14:37:02 +00:00
Ben Gras
3e29947e28 No more HZ; move stacktrace() to library 2008-12-11 14:36:37 +00:00
Ben Gras
825dfb0282 introduce Hz variable that is what used to be the HZ constant.
default 60Hz of course.
2008-12-11 14:33:33 +00:00
Ben Gras
4c1ac39678 Changes so the HZ constant isn't needed any more. 2008-12-11 14:27:18 +00:00
Ben Gras
37a9ce7275 I want to see /dev/imgrd so I can unmount it when it's free. 2008-12-11 14:26:50 +00:00
Ben Gras
5aea2817bc syslogd needs a bit more stack. 2008-12-11 14:26:27 +00:00
Ben Gras
9d096e014b . print kernel stacktrace unconditionally on panic
. provide a panic() in the kernel for if a library function wants to panic
2008-12-11 14:23:58 +00:00
Ben Gras
b61687fb1b . VM needs a higher priority than VFS, PM etc
. introduce FULLVM flag: MEMORY and the initial MFS
   get their own full address spaces, making their stacks
   and heaps not preallocated (well, freed after VM has
   initialized it) and letting them allocate more dynamically.
   MEMORY in particular needs this to map in physical memory
   using its own page table, without having to allocate.
2008-12-11 14:21:47 +00:00
Ben Gras
034b5c6042 PM_PROC_NR shouldn't be hardcoded as the caller. 2008-12-11 14:18:51 +00:00
Ben Gras
66b161238d function to increase process stack (pointer). used by VM to set up large,
sparse, non-preallocated heap and stack.
2008-12-11 14:17:45 +00:00
Ben Gras
e911d44a5c system image processes with full address space are allowed to have pagefaults. 2008-12-11 14:16:40 +00:00
Ben Gras
c4fb567bd5 . replace HZ by runtime system_hz (sysenv variable 'hz')
. new flag PROC_FULLVM in table indicating process wants full address
   space (this is then created and managed by VM)
2008-12-11 14:15:23 +00:00
Ben Gras
afef5e0711 . some flags to <minix/const.h>
. add system_hz for runtime HZ value
2008-12-11 14:12:52 +00:00
Ben Gras
dd9e9c74cd vm map request - ioctl to /dev/video 2008-12-11 14:11:59 +00:00
Ben Gras
3f30c3a0ee add va_copy() 2008-12-11 14:10:56 +00:00
Ben Gras
9bbee4f1ce 2008-12-11 14:10:37 +00:00
Ben Gras
e75e231abc VMCTL_INCSP to increase process stack pointer.
(Used to change the virtual address of the stack before a process has
started executing.)
2008-12-11 14:10:17 +00:00
Ben Gras
682b9a872e . ser_putc() goes to library
. another cmd for getinfo - obtaining current HZ value
2008-12-11 14:09:38 +00:00
Ben Gras
ef5b6f8cdf . HZ no longer constant, but settable at boot time; default is DEFAULT_HZ (60)
. some kernel flags to <minix/const.h>
2008-12-11 14:08:53 +00:00
Ben Gras
a74132ec69 fix race condition that can trigger 'enqueue already ready process' panic. 2008-12-11 13:42:37 +00:00
Ben Gras
567f2f0ba0 umap fix 2008-12-08 17:06:38 +00:00
Ben Gras
68d0c4defe - code shared with exec() letting boot-time processes have
their own fully fledged virtual address space and freeing
   their pre-allocated heap+stack area (necessary to let memory
   driver map in arbitrary areas of memory for /dev/mem without
   sys_vm_map)
 - small optimization preallocating memory on exec
 - finished VR_DIRECT physical mapping code
2008-12-08 16:43:20 +00:00
Ben Gras
f4d0d635fd - hz dynamic
- new map /dev/video implementation
 - ser_putc into library
2008-12-08 16:40:29 +00:00
Ben Gras
fe56202038 floppy must be able to allocate a bit more for nonpaged mode. 2008-11-19 17:31:42 +00:00
Ben Gras
9b33056d2b make allocmem accept and return values in bytes, ramdisk expects this. 2008-11-19 15:40:17 +00:00
Ben Gras
51fdce1d36 minor fixes 2008-11-19 14:10:33 +00:00
Ben Gras
6c92081a5a paged mode is default. 2008-11-19 13:19:37 +00:00
Ben Gras
16e14559e6 include libraries. 2008-11-19 13:15:35 +00:00
Ben Gras
7b3d952a77 lingering file 2008-11-19 12:38:31 +00:00
Ben Gras
b686e8b6d7 lingering file. 2008-11-19 12:35:46 +00:00
Ben Gras
c078ec0331 Basic VM and other minor improvements.
Not complete, probably not fully debugged or optimized.
2008-11-19 12:26:10 +00:00
Philip Homburg
c888305e21 Reverted accidental change to stat.c. 2008-10-02 14:11:12 +00:00
Philip Homburg
005bc7a649 Some changes that were missing from the previous commit 2008-10-02 13:48:05 +00:00
Philip Homburg
5b5b54c76c Minix 3 version 2008-10-02 13:45:46 +00:00
Philip Homburg
659ab96c1f Unmodified source of the software fault injection utility 2008-10-02 13:43:32 +00:00
Ben Gras
58f428a704 throw out two time consuming tests 2008-10-01 15:09:33 +00:00
David van Moolenbroek
e8b863702a Added lance entry to drivers.conf. 2008-07-22 15:11:01 +00:00
David van Moolenbroek
f73b541952 Backport of fix from asynchvfs branch for PM-LOG-VFS-PM deadlock that resulted in VFS panics. 2008-06-24 13:53:03 +00:00
Ben Gras
39aa2e6489 A glob() implementation. 2008-04-08 13:14:33 +00:00
Ben Gras
d939a9c54b Use $PAGER if set. Suggested by gigabo at gmail.com. 2008-04-08 12:34:35 +00:00
Philip Homburg
4696d74480 Select support for eth by Erik van der Kouwe. 2008-03-12 14:10:21 +00:00
Philip Homburg
60c1131b94 SYS_MAPDMAx -> SYS_MAPDMA, added IOMMU_MAP 2008-02-25 14:39:19 +00:00
Philip Homburg
9d41dbc55e Build libdriver_asyn for target image 2008-02-25 14:38:09 +00:00
Philip Homburg
9d62f56ea1 SYS_MAPDMAx -> SYS_MAPDMA. 2008-02-25 14:36:28 +00:00
Philip Homburg
f82a1c4df7 Fixed include files. 2008-02-25 14:35:54 +00:00
Philip Homburg
a508e0a03c _function, function -> call_nr 2008-02-25 14:35:11 +00:00
Philip Homburg
822fcd368d Added O_REOPEN, better error handling. 2008-02-25 12:13:30 +00:00
Philip Homburg
41efa40ad2 Added XDOPEN. 2008-02-25 12:12:07 +00:00
Philip Homburg
9d176133ee Added libdriver_asyn and amddev 2008-02-25 12:07:48 +00:00
Philip Homburg
4474166403 Driver for AMD's DEV. 2008-02-25 12:07:19 +00:00
Philip Homburg
a51dbad054 Asynchrnous character device interface. 2008-02-25 11:54:04 +00:00
Philip Homburg
65df875abb Need separate 'prev_next' pointers for kernel and TTY. 2008-02-25 11:53:37 +00:00
Philip Homburg
830b79f0d5 Link random number genertor with libdriver_asyn 2008-02-25 10:25:43 +00:00
Philip Homburg
bc125e3e1c Copy of libdriver for asynch interface to character drivers. Has to be cleaned
up.
2008-02-25 10:24:46 +00:00
Philip Homburg
404325b193 Support for I/O MMU. 2008-02-25 10:19:29 +00:00
Philip Homburg
668515afe2 More heap for fxp, support for I/O MMU. 2008-02-25 10:12:09 +00:00
Philip Homburg
54f714e59e Respond to RS ping request, asynch interface, register with I/O MMU. 2008-02-25 10:02:24 +00:00
Philip Homburg
00ef93d6a2 Use nonblocking sends to reply, fixed reply message for DIAGNOSTICS(_S) 2008-02-22 16:03:00 +00:00
Philip Homburg
e3d4c74393 Functions that check arguments and return a status code and functions that
don't.
2008-02-22 15:59:12 +00:00
Philip Homburg
fecd153c2c Declare and call functions that check arguments and return a status code. 2008-02-22 15:56:12 +00:00
Philip Homburg
8a07b7687a Use nonblocking send to reply. 2008-02-22 15:52:13 +00:00
Philip Homburg
bc7e3c02a3 Asynchronous select implementation. 2008-02-22 15:46:59 +00:00
Philip Homburg
ff7eae2ad8 Private copy of kputc to support asynch communication with log device. 2008-02-22 15:43:33 +00:00
Philip Homburg
2ec762c60c Asynchronous communication with character specials. 2008-02-22 15:41:07 +00:00
Philip Homburg
d9a9b727e2 Added dmap_async_driver and dmap_sel_filp fields. Support for asynch character
drivers (needs cleaning up).
2008-02-22 15:01:00 +00:00
Philip Homburg
9df94c5ee8 Use dev_t instead of Dev_t in structures. 2008-02-22 14:54:00 +00:00
Philip Homburg
097d8fee66 Use nonblocking send for reply. Support for asynchronous message passing
(needs cleaning up).
2008-02-22 14:53:02 +00:00
Philip Homburg
66c930ef8b Higher NCALLS requires bigger table. New calls are in PM. 2008-02-22 14:51:38 +00:00
Philip Homburg
93ff4c327f Added XDOPEN. 2008-02-22 14:50:41 +00:00
Philip Homburg
9388a27070 Support for O_REOPEN flag and pass the filp numbet to dev_open. 2008-02-22 14:49:02 +00:00
Philip Homburg
7387449b23 Support for suspending on character device open and on drivers that need to
be restarted.
2008-02-22 14:47:40 +00:00
Philip Homburg
ca91b3b5be New fp_flags. Currently used to signal that is process should be suspended
a driver is restarted.
2008-02-22 14:32:23 +00:00
Philip Homburg
6ef71b8198 Pass suspend_reopen flag to dev_io. 2008-02-22 14:26:41 +00:00
Philip Homburg
047cc090e4 Added filp_state for driver recovery and filp_select_flags to store select
state for character specials that use asynch I/O.
2008-02-22 14:19:23 +00:00
Philip Homburg
1d7d5aa629 dev_close needs the filp number for asynch I/O, dev_io gets suspend_reopen
flag to suspend a process until the filedescriptor is re-opened. Added 
dev_reopen, asyn_io, suspended_ep, reopen_reply, asynsend, diag_repl, 
close_filp, close_reply, unpause, select_reply1, select_reply2.
2008-02-22 14:03:14 +00:00
Philip Homburg
e5df351245 Support for blocking open on char specials (due to asynch message passing),
asynch. close, added close_filp function.
2008-02-22 13:57:11 +00:00
Philip Homburg
73ea967b6c Keep track of error statistics, rate limit debug output, added SYS_MAPDMA. 2008-02-22 12:38:22 +00:00
Philip Homburg
992edfd558 Keep track of various statistics related to IPC and SYSTEM. 2008-02-22 12:36:46 +00:00
Philip Homburg
5996d1de58 Added do_mapdma. 2008-02-22 12:25:59 +00:00
Philip Homburg
f6872f8323 Added ipc_stats_target. 2008-02-22 12:25:44 +00:00
Philip Homburg
4a86b1fea5 Changes to debug output, mostly rate limiting. 2008-02-22 11:00:06 +00:00
Philip Homburg
3c2e122d6d Disabled code to set ipc_stats_target. 2008-02-22 10:58:27 +00:00
Philip Homburg
2679321ba0 Added do_mapdma. 2008-02-22 10:51:37 +00:00
Philip Homburg
594035f13c More verbose (optional) debug output for exceptions. 2008-02-22 10:43:18 +00:00
Philip Homburg
f5389ecf19 Code to dump IPC statistics over a serial line. (Disabled) code to disable the
FPU.
2008-02-22 10:40:38 +00:00
Philip Homburg
1cffa69d2c Support for I/O MMU: do not re-use a memory segment until the I/O MMU has
removed it from its map.
2008-02-21 16:33:34 +00:00
Philip Homburg
75520b7403 ipc restrictions for some drivers and I/O MMU (amddev) 2008-02-21 16:24:35 +00:00
Philip Homburg
3f23bca404 Removed defines not needed by mfs (XPIPE, XLOCK, XPOPEN, XSELECT, DUP_MASK). 2008-02-21 16:22:36 +00:00
Philip Homburg
ca8291c815 Support for restricting limiting IPC to a set of endpoints. Not enabled by
default, pass -i to service. Do not reply to bogus request types. Reply using
sendnb.
2008-02-21 16:20:22 +00:00
Philip Homburg
19db2b646e Removed superfluous argument. 2008-02-21 16:09:58 +00:00
Philip Homburg
d9858cfabf Removed some debug output. 2008-02-21 16:08:08 +00:00
Philip Homburg
4951a741b0 adddma/deldma/getdma/sys_mapdma 2008-02-21 16:02:22 +00:00
Philip Homburg
959ed5a191 Added ERESTART 2008-02-21 16:00:39 +00:00
Philip Homburg
07c258a9c7 Added adddma/deldma/getdma. 2008-02-21 15:58:55 +00:00
Philip Homburg
e674f1a54f Added ERESTART. 2008-02-21 15:58:26 +00:00
Philip Homburg
3b3fc8a9c4 Added O_REOPEN. 2008-02-21 15:58:06 +00:00
Philip Homburg
82cb46af0a Changes for asynchronous interface to character specials.
Removed DEV_SEL_WATCH. Added SYS_MAPDMAx. New message type (DIAG_REPL) for
replies to DIAGNOSTICS(_S).
2008-02-21 15:57:35 +00:00
Philip Homburg
698df384c3 Extra calls to PM for I/O MMUs. 2008-02-21 15:51:27 +00:00
Philip Homburg
cb2b7ada63 Nonblocking send. 2008-02-21 15:50:09 +00:00
Philip Homburg
fc4593fb42 List of service/driver names that are allowed as IPC endpoints for a new
driver/service.
2008-02-21 15:49:44 +00:00
Philip Homburg
124a128736 Defines for AMD I/O MMU 2008-02-21 15:47:11 +00:00
Ben Gras
2c45324c47 keymap contributed by Roman Ignatov. 2008-02-06 15:16:50 +00:00
Ben Gras
2876d5c4ba Optimization in searching for new zones to allocate contributed
by Jens de Smit.
2008-02-06 15:05:57 +00:00
Ben Gras
cd89066f9a Trust $PATH. 2007-12-19 10:51:21 +00:00
Ben Gras
b250847120 Makefile for audio drivers. 2007-12-19 10:37:29 +00:00
Ben Gras
8e727c97ce always re-enable irq, so devices sharing this irq don't go deaf
as IRQ_REENABLE isn't specified.
2007-12-14 12:44:20 +00:00
Ben Gras
50fa859819 A rint() implementation. 2007-12-14 11:59:54 +00:00
Ben Gras
bd489b6c0b Original imported versions of s_rint.c and math_private.h. 2007-12-11 12:32:26 +00:00
Ben Gras
3f2230eee5 add M_SQRT1_2 (1/sqrt(2)) 2007-12-11 10:59:02 +00:00
Ben Gras
e39af6d1ff yearly fsck increase. 2007-12-11 10:51:35 +00:00
Ben Gras
45744bff41 Connect new audio drivers to build. 2007-11-23 11:53:33 +00:00
Ben Gras
b79b305ba1 More es1371 bij Pieter Hijma. 2007-11-23 11:52:34 +00:00
Ben Gras
c67a56708e es1370 driver and updated es1371 and framework by Pieter Hijma. 2007-11-23 11:40:33 +00:00
Ben Gras
0d2d8c6db2 audio drivers. (not updated for trunk.)
sb16: port of isa sb16 driver to user-space. Port by Peter Boonstoppel.
es1371: By Laurens Bronwasser.
2007-11-23 11:30:50 +00:00
Ben Gras
1327804478 MFS doesn't need sys_exit(). 2007-10-23 14:24:41 +00:00
Ben Gras
67d1b67805 exit prototype 2007-10-23 14:19:16 +00:00
Ben Gras
e8aec69c7b tweak to panic functions of mfs and vfs.
. print newline
  . when recursive panic detected, don't simply return, confusing
    the caller, but print a diagnostic and exit
  . don't call sys_exit as this may confuse PM; it should be OK
    to call PM exit() nowadays.
2007-10-23 14:17:51 +00:00
Ben Gras
515e8216e1 Basic entry for dpeth suggested by Jens de Smit. 2007-10-17 11:02:33 +00:00
Ben Gras
0ae1ff99b8 Fix for DL_STAT_REPLY/DL_TASK_REPLY
Bug found and fixed by Jens de Smit <jfdsmit at few.vu.nl>.
2007-10-17 10:53:47 +00:00
Ben Gras
23f6e478df Fixed a glitch introduced in safe i/o conversion. 2007-10-17 10:50:18 +00:00
Ben Gras
21ae963cf1 Fixes two wrong grant return checks and one 'grant leak'. 2007-10-17 10:46:20 +00:00
Ben Gras
af591d2151 Internally, floppy driver still used vircopies ('unsafe' copies), but
this isn't allowed in its drivers.conf entry. Changed these to memcpy()
calls.  Bug reported by Maurizio Lombardi in comp.os.minix.
2007-10-16 14:31:35 +00:00
Ben Gras
b6e07e1835 close device if mount fails after device opened. 2007-09-26 15:06:41 +00:00
Philip Homburg
b74b3315a3 Added PF_UNIX and PF_INET to make porting easier. 2007-09-17 11:35:44 +00:00
Philip Homburg
af678531aa Disabled some debug output in recvfrom. 2007-09-17 11:22:06 +00:00
Ben Gras
38604e4e3a Don't truncate read requests based on v_size; v_size can be stale in the
case of directories extended by subfilesystem. Rely on subfilesystem to
do read size truncating and return actual i/o size. This fixes bug 81 in
gforge, and unbreaks test 23.
2007-09-11 15:52:22 +00:00
Ben Gras
007bb33c7d Make test 17 use dir 17 2007-09-11 14:56:48 +00:00
Ben Gras
ff9f4dd59c fix for i/o data/addr pair set macro's. 2007-09-11 11:22:29 +00:00
Philip Homburg
ab3062c8c0 REQ_FSTATFS now operates on the root inode (the inode parameter has been
removed)
2007-08-17 11:20:59 +00:00
Philip Homburg
9c3f85d14f Better interface for sys_times. 2007-08-16 13:16:26 +00:00
Philip Homburg
341270673b mfs no longer needs access to VIRCOPY, Added rs.inet. Start inet with
rs.inet as the restart script.
2007-08-15 12:56:35 +00:00
Philip Homburg
4b1cd8c0ec Return EIO if a filedescriptor cannot be re-opened after a driver restart.
Select now returns such a filedescriptor as ready (instead of EBADF). 
Reply before dev_up in FSSIGNON to avoid the problem that a DEV_OPEN
request is received by a driver that expects a reply from the FSSIGNON.
2007-08-15 12:53:52 +00:00
Philip Homburg
c26de9f435 Close UDP socket after error. 2007-08-15 12:50:24 +00:00
Philip Homburg
90fde6e97d cleanup 2007-08-10 13:02:39 +00:00
Philip Homburg
06e1f0da61 Better recovery when req_readsuper fails. 2007-08-10 13:01:38 +00:00
Philip Homburg
57c6f099f2 Removed old debug code. 2007-08-08 15:27:07 +00:00
Philip Homburg
e2f06e7c89 Directory check before access check. 2007-08-08 15:26:47 +00:00
Philip Homburg
a116b3aa55 To return the right error, check first is an object is a directory (for
mkdir, rmdir/unlink, mknod), simply pipe code by using v_pipe_rd_pos and
v_pipe_wr_pos directly. Some cleanup work in open.c
2007-08-08 14:01:36 +00:00
Philip Homburg
c2bf536a55 Disable POSIX-required behavior wrt trailing slashes. 2007-08-08 11:40:47 +00:00
Philip Homburg
d232b2ef42 Removed invalid consistency check. 2007-08-07 14:27:19 +00:00
Philip Homburg
9c51f0b92a O_EXCL check went missing. 2007-08-07 14:26:56 +00:00
Philip Homburg
d01d630727 include "../vfs/dmap.h". 2007-08-07 13:26:25 +00:00
Philip Homburg
1b883a3613 Removed references to stacktrace. 2007-08-07 13:21:55 +00:00
Philip Homburg
a318cd291f Somehow request.c got garbled. 2007-08-07 13:12:27 +00:00
Philip Homburg
f46319037b New VFS interface 2007-08-07 12:52:47 +00:00
Philip Homburg
2ca2b86a3a Added new interface to VFS. 2007-08-07 12:38:35 +00:00
Philip Homburg
a81e82b3da Tell the kernel about the new boottime and don't tell VFS.
Tell DS about all processes in the boot image. PM_STIME is removed.
Diagnostic for calls to do_getprocnr (DS should be used to get endpoints).
2007-08-07 12:28:42 +00:00
Philip Homburg
fd151245e9 Removed sigaction call. PM tries to talk to DS. DS should not talk to PM. 2007-08-07 12:25:21 +00:00
Philip Homburg
1f04287b3f Removed dmap table. Publish endpoint in DS before calling mapdriver5. 2007-08-07 12:24:06 +00:00
Philip Homburg
6ef2e9b866 Added global variable boottime, prototype for do_stime, and table entry for
SYS_STIME.
2007-08-07 12:21:40 +00:00
Philip Homburg
fab77fd01f Added do_stime.c, return boot time in do_times.c 2007-08-07 12:20:31 +00:00
Philip Homburg
4f787035ea Removed check for grants that wrap. 2007-08-07 12:19:45 +00:00
Philip Homburg
2519a7cb61 Added getuptime2.c 2007-08-07 12:14:04 +00:00
Philip Homburg
5aa84fb0e6 Added mapdriver5.s. 2007-08-07 12:05:36 +00:00
Philip Homburg
21e7edb683 Added sys_stime.c, T_CHILD_UTIME and T_CHILD_STIME are gone, should
change interface of sys_times.
2007-08-07 12:04:29 +00:00
Philip Homburg
1f02168ce7 Added _mapdriver5.c. 2007-08-07 12:02:38 +00:00
Philip Homburg
4d2f56daf6 Added prototype for mapdriver5 (from RS to VFS, report the name of a driver
instead of its endpoint).
2007-08-07 11:59:02 +00:00
Philip Homburg
6b0db0d181 Many changes to the VFS/FS interface. 2007-08-07 11:58:03 +00:00
Philip Homburg
d9166df3f7 Added FS_READY (from vfsif.h), and MAPDRIVER (from RS to VFS) 2007-08-07 11:57:33 +00:00
Philip Homburg
23fd914307 New message type 9: 5 longs, 3 shorts, and 2 chars. 2007-08-07 11:56:28 +00:00
Philip Homburg
498728bdbe New call SYS_STIME, restructured fields for SYS_TIMES, removed PM_STIME,
added VFS_BASE.
2007-08-07 11:55:28 +00:00
Philip Homburg
fc0d7995e9 Some parts of dmap can be private (to vfs) 2007-08-07 11:53:41 +00:00
Philip Homburg
bf6620d285 Added prototypes for sys_stime and getuptime2 (tell the kernel about the
boot time and return the boot time together with the uptime)
2007-08-07 11:52:15 +00:00
Philip Homburg
2a58d1dc58 Constants for symlink loops 2007-08-07 11:43:49 +00:00
Philip Homburg
1d4afb3599 Compile-time option to duplicate console output to the first serial line 2007-08-07 11:27:03 +00:00
Philip Homburg
acfaea0fa2 More space on ramdisk 2007-08-07 11:22:35 +00:00
Philip Homburg
f352a3fb15 Print the value of a capability as well. 2007-08-07 11:21:57 +00:00
Ben Gras
a80365f407 . add checks to printer driver kernel calls
. correct some i/o locations for printer in drivers.conf
2007-08-06 11:17:08 +00:00
Ben Gras
03446f5554 micro_delay in sysutil, used in ti1225, dp8390, fxp and
orinoco now. Uses a combination of tickdelay (where possible) and
calibrated busywait (where necessary).
2007-07-31 15:01:49 +00:00
Ben Gras
2dc2db4ba1 'fix' crlf style 2007-07-24 14:49:39 +00:00
Ben Gras
816f5dd550 a driver for wireless pci cards with the Prism chipset from Intersil
Original version, by Stevens Le Blond and Michael Valkering.
2007-07-24 14:49:09 +00:00
Ben Gras
e2932a1180 . remove small image (doesn't fit)
. edparams line a bit more readable
 . use image built in build tree, not regular source tree
2007-07-17 14:36:42 +00:00
Ben Gras
cd4756933a Typo reported by Johnathan Gurley. 2007-07-17 11:40:02 +00:00
Ben Gras
30ba1ec187 also allow vm_map. 2007-07-11 13:45:06 +00:00
Ben Gras
eb4609c108 Don't exit when rebooting. 2007-07-11 13:44:45 +00:00
Ben Gras
d524b0b351 Don't quit (some processes want to talk to pci at reboot time) 2007-07-11 13:44:00 +00:00
Ben Gras
ee3e40516b . clarify panic messages in syslib about pci
. use ds_retrieve_u32 instead of _pm_findproc
2007-07-11 13:38:13 +00:00
Ben Gras
c829928cf1 Give arp and install the default amount of memory - otherwise they run
out of memory in extreme cases.
2007-07-11 13:36:31 +00:00
Ben Gras
2746a5a2a9 Reported by Erik van der Kouwe <vdkouwe at cs.vu.nl>:
-  fprintf(stderr, "%s: reboot(): %s\n", strerror(errno));
+  fprintf(stderr, "%s: reboot(): %s\n", prog, strerror(errno));
  
Other minor fixes inspired by other warnings produced by gcc.
2007-07-02 11:16:27 +00:00
Ben Gras
ad93329236 Assume bios parameters are wrong/missing if any of the parameters are 0. 2007-05-30 16:13:52 +00:00
Ben Gras
ed920a691d include 'printer' driver 2007-05-30 15:40:12 +00:00
Ben Gras
b918f61820 Boot monitor flag that enables 'sticky right-alt', permanent change
to col selected from the keymap untill right-alt is pressed again.

Sticky alt code and russian keymap contributed by Roman Ignatov
and Yaroslav Schekin.
2007-05-16 13:14:37 +00:00
Ben Gras
b6cd5d0351 Include fonts blobs in src repository. 2007-05-16 13:00:43 +00:00
Ben Gras
b00f287449 Restore user-owned bits from PSW after a signal handler, instead of
copying complete PSW after signal handler.

This fixes a psw corruption bug reported by Jens de Smit <jst260@few.vu.nl>.
2007-05-08 15:43:00 +00:00
Philip Homburg
56a68dc32b Hack in service to use RS_START instead of RS_UP. RS reports the use of RS_UP. 2007-05-02 15:20:28 +00:00
Philip Homburg
2db15eaa80 Added fxp. rtl8139 doesn't need to be root anymore. 2007-05-02 11:40:15 +00:00
Philip Homburg
2d49b4ecb5 Use ds_retrieve_u32 to get the endpoint of inet. 2007-05-02 11:39:10 +00:00
Philip Homburg
a124958e59 Use ds_retrieve_u32 to get the endpoint of inet. 2007-05-02 11:32:22 +00:00
Philip Homburg
33d31720a5 Use ds_retrieve_u32 to get the endpoint of inet and of the ethernet drivers. 2007-05-02 11:30:16 +00:00
Philip Homburg
9852471c08 Use ds_retrieve_u32 to find the endpoint of pci. 2007-05-02 11:24:51 +00:00
Ben Gras
47c18edb26 date not built from here 2007-05-01 14:18:55 +00:00
Ben Gras
b49ba611bd shell at least as big in 'big' as in normal 2007-05-01 14:11:10 +00:00
Philip Homburg
02a229f14d Publish endpoints in ds. 2007-04-27 13:03:33 +00:00
Philip Homburg
93f9bb4a57 Restrict access to rs to root's processes. 2007-04-27 12:27:40 +00:00
Philip Homburg
69ca935251 getpeuid implementation. Get the uid of a process (by endpoint) 2007-04-27 12:21:06 +00:00
Ben Gras
8eb09f6ddc . readall: use lseek64() to read more than 4GB of a device
. vfs: 64-bit offset support for character device i/o
   (also remove unused dev_bio function)
 . memory: /dev/null and /dev/zero are infinitely large, don't stop
   reading/writing at 4GB
2007-04-24 13:27:33 +00:00
Ben Gras
cc7c561d41 obsolete manpages (these have become packages) 2007-04-24 13:25:57 +00:00
Philip Homburg
0dc0d3fe5b Fixed releasing PCI resources after a driver terminates. 2007-04-24 12:55:37 +00:00
Ben Gras
ac64c1b3dc Take out obsolete message about 4GB. 2007-04-24 12:40:25 +00:00
Ben Gras
72e6862e4e dp8390 doesn't cope with the different semantics of the pci
functions.

Bug and workaround reported by "E.Agafonov" <e.a.agafonov@gmail.com>.
2007-04-24 12:29:51 +00:00
Philip Homburg
cab8f526de Fixed some lose ends in the serial line debug dump code. 2007-04-23 15:59:16 +00:00
Philip Homburg
29f7031340 Remove KILL and VIRCOPY from drivers that don't need them. Added rtl8139. 2007-04-23 15:39:46 +00:00
Philip Homburg
50f81c4939 Ethernet driver changes for asynchronous inet. 2007-04-23 15:38:00 +00:00
Philip Homburg
bb659b1ad6 Disabled ser_putc for reporting debug internal to tty over the serial line.
Disabled return statement for serial debug input in the kernel.
2007-04-23 14:59:32 +00:00
Philip Homburg
a3c8619923 Added do_del_acl. More detailed debug output for the secure device capability. 2007-04-23 14:54:51 +00:00
Philip Homburg
0bd4c5ee7d Initial convertion to asynchronous sends for communicating with ethernet
drivers.
2007-04-23 14:49:20 +00:00
Philip Homburg
b613f5cb4b Report and detect exec failures using a pipe.
XXX Hardcoded values for s_ipc_to and s_ipc_sendrec.
2007-04-23 14:47:04 +00:00
Philip Homburg
727ce18aa8 Initialize exec_pipe. 2007-04-23 14:43:25 +00:00
Philip Homburg
849285f66d Diagnostics from service go to standard error. 2007-04-23 14:42:58 +00:00
Philip Homburg
e68a2b4d6a Extra flags RS_SIGNALED and RS_EXECFAILED. Pipe for detecting exec failures. 2007-04-23 14:42:08 +00:00
Philip Homburg
b4a88a3705 Removed ECHO from dump, added SENDA. Also dump s_ipc_sendrec. 2007-04-23 14:40:13 +00:00
Philip Homburg
77f5b40141 Round memory size up for VM. 2007-04-23 14:38:55 +00:00
Philip Homburg
b5e6319ae7 Removed some indentation. 2007-04-23 14:33:42 +00:00
Philip Homburg
13da935060 Debug dumps over the serial line. Direct output to video memory. 2007-04-23 14:25:17 +00:00
Philip Homburg
c59b23859e Clean and support for asynchronous sends. 2007-04-23 14:24:30 +00:00
Philip Homburg
47233bdf30 Fixed bad boundary condition, support for asynchronous I/O. 2007-04-23 14:23:37 +00:00
Philip Homburg
c7a7c0cb17 Removed some white space. 2007-04-23 13:58:37 +00:00
Philip Homburg
94bc849574 Poll serial line for debug output requests when do_serial_debug is true. 2007-04-23 13:56:27 +00:00
Philip Homburg
8937b6a8de Initialize s_ipc_sendrec. 2007-04-23 13:46:54 +00:00
Philip Homburg
da4bb9144d Removed ECHO. 2007-04-23 13:46:26 +00:00
Philip Homburg
f41429d815 Cleanup. 2007-04-23 13:44:56 +00:00
Philip Homburg
cb3e271b24 Fields for asynchronous sends (s_asyntab and s_asynsize) and for allowed
sendrecs (s_ipc_sendrec).
2007-04-23 13:37:30 +00:00
Philip Homburg
6554f3d3dc Added MF_ASYNMSG. 2007-04-23 13:36:38 +00:00
Ben Gras
1d7cea10ed str[] is too small - reported by Erik van der Kouwe <vdkouwe@cs.vu.nl>. 2007-04-23 13:36:13 +00:00
Philip Homburg
8eb27a714e More debug output. Dump kernel process on serial line. Directly put
text in video memory.
2007-04-23 13:36:11 +00:00
Philip Homburg
c082f607df Disallow unaligned access to I/O ports. 2007-04-23 13:31:45 +00:00
Philip Homburg
d2cec7db49 Disallow unaligned access to I/O ports. 2007-04-23 13:31:16 +00:00
Philip Homburg
7541e0753b Separate permissions for sendrec. Actually initialize send/sendrec permissions
for data supplied by rs.
2007-04-23 13:30:04 +00:00
Philip Homburg
d80e25068c GET_PRIVID: return the ID of a process' privilege structure. 2007-04-23 13:28:14 +00:00
Philip Homburg
2b2d3d5131 Fail unsafe sdevio. Disallow unaligned I/O ports. 2007-04-23 13:22:26 +00:00
Philip Homburg
bc17115a34 Prototypes for exception and stacktrace. Declare additional arguments
for exception to be able to print nexted exceptions.
2007-04-23 13:19:25 +00:00
Philip Homburg
b4f6994278 Use sprintf to avoid buffer overflows. 2007-04-23 13:04:31 +00:00
Philip Homburg
82e77742b5 Added pci_del_acl. Fixed return value of pci_set_acl. 2007-04-23 12:14:44 +00:00
Philip Homburg
4ce2267dd3 Type _exit and abort before generating a trap. 2007-04-23 12:13:51 +00:00
Philip Homburg
4ce9ca03cf Added cpf_reload to reload the safecopy table pointer (for example after a
fork).
2007-04-23 12:12:32 +00:00
Philip Homburg
e9899f3c86 Added sendnb and senda, removed echo and _ipcnew.s. 2007-04-23 12:11:03 +00:00
Philip Homburg
35c3f52d99 Renamed BUSC_PCI_ACL to BUSC_PCI_SET_ACL, added BUSC_PCI_DEL_ACL.
Added DL_STAT_REPLY and GET_PRIVID.
2007-04-23 12:01:47 +00:00
Philip Homburg
555bc29a0c sys_getprivid macro to get the ID of a process' privilege structure.
Prototype for pci_del_acl.
2007-04-23 12:00:46 +00:00
Philip Homburg
36c764be1c Asynchronous send. 2007-04-23 11:59:19 +00:00
Philip Homburg
a17ff08fb9 Prototype for cpf_reload. 2007-04-23 11:58:41 +00:00
Ben Gras
ac41dcd35f bc and mtools out of the base system (gpl) 2007-04-20 12:06:14 +00:00
Ben Gras
0a0f800805 Make mkfs message a bit clearer. 2007-04-19 14:13:27 +00:00
Ben Gras
3b614085c6 Don't limit partitions to 4GB. 2007-04-19 14:08:41 +00:00
Ben Gras
365e867a88 Some features for the automatic image build. 2007-04-18 11:42:48 +00:00
Ben Gras
673c7ced15 Print svn rev and date info in /etc/version. 2007-04-18 11:39:18 +00:00
Ben Gras
8aa0d26891 update binary_sizes to not make binaries smaller than the build does. 2007-04-17 13:50:58 +00:00
Ben Gras
b015dae3e7 fix packman cd/net quirks 2007-04-13 17:13:53 +00:00
Ben Gras
dc67b37a10 more removing of warning and debug messages. 2007-04-13 14:00:31 +00:00
Ben Gras
4e0316611a update boot message for prerelease 2007-04-13 10:00:29 +00:00
Ben Gras
6b2ad6fdfd verbose message out 2007-04-12 17:01:54 +00:00
Ben Gras
a2b1a5134b . leave out hardware-fp code from library
. minor packman usage tweaks
 . kernel feature for printing version number
 . removed some verbose debug messages from vfs/mfs
2007-04-12 16:45:00 +00:00
Ben Gras
7dd225ffb2 delete redundant source 2007-04-12 16:30:59 +00:00
Ben Gras
2958815463 leave out debug message 2007-04-12 15:24:45 +00:00
Ben Gras
9200a8a253 feature to display svn version on kernel boot 2007-04-12 15:13:10 +00:00
Ben Gras
691b09f232 This will become 3.1.3 2007-04-12 14:31:16 +00:00
Ben Gras
d61a481169 put the zoneinfo library files directly in the lib/stdtime dir 2007-04-12 14:29:30 +00:00
Ben Gras
ef8ec86b78 Don't always update CMOS on shutdown. 2007-04-10 13:40:09 +00:00
Ben Gras
18e7b315a1 remove debug message 2007-04-05 13:58:35 +00:00
Ben Gras
01c0669075 Bigger shell 2007-04-05 12:30:24 +00:00
Ben Gras
57a5797045 no /usr/gnu/man in base system 2007-04-05 10:52:20 +00:00
Ben Gras
7b4cfd585a as needs more. 2007-04-05 10:47:04 +00:00
Ben Gras
3354ba1b6c . add /usr/share for zoneinfo
. throw out non-base /usr/gnu stuff
2007-04-05 10:37:22 +00:00
Ben Gras
21e61a600d /bin/echo is used during early bootstrap too. 2007-04-04 13:05:13 +00:00
Ben Gras
4928e42efb fix packman sort col, and make sort case-insensitive 2007-04-02 16:23:55 +00:00
Ben Gras
70b95c31bc version /usr/lib/crontab too 2007-04-02 16:18:46 +00:00
Ben Gras
9581f1596f explanations with common test3 errors. 2007-04-02 16:00:06 +00:00
Ben Gras
85198a280c fix some compiler warnings. 2007-04-02 15:10:07 +00:00
Ben Gras
647d1496f3 fix for warning 2007-04-02 14:45:56 +00:00
Ben Gras
321622a318 accept 'q' to exit. 2007-04-02 14:44:16 +00:00
Ben Gras
c0ed0de7d1 mount needs more memory to do system() for rs_down in the event a mount fails. 2007-04-02 14:41:06 +00:00
Ben Gras
c808aeb74e fix off-by-one error in 'all' 2007-04-02 12:09:43 +00:00
Ben Gras
735d605330 remove debug line 2007-03-30 15:55:36 +00:00
Ben Gras
056ac0a0d3 replace library time handling functions
mktime, tzset, asctime, ctime, gmtime, localtime, strftime
with zoneinfo implementations in src/commands/zoneinfo, referenced
from src/lib/stdtime/Makefile.in.
2007-03-30 15:36:49 +00:00
Ben Gras
6ccd37a982 fix for filenames with paths 2007-03-30 15:35:15 +00:00
Ben Gras
0be7f44224 . added zoneinfo to build, with fixes for minix
. now using zoneinfo date command, instead of commands/simple/date.c
2007-03-30 15:32:55 +00:00
Ben Gras
a2d3b518d8 rename svn revision variable to one with underscore, to not pollute
application namespace
2007-03-30 15:17:32 +00:00
Ben Gras
7507ebfeca remove debug message 2007-03-30 15:17:03 +00:00
Ben Gras
f3f2e92191 move date(1) to minix manual page place. 2007-03-26 11:24:13 +00:00
Ben Gras
288ee57135 tz database is in /usr/share/zoneinfo. 2007-03-26 11:22:20 +00:00
Ben Gras
fedb5c0368 make way for new date(1). 2007-03-26 11:21:54 +00:00
Ben Gras
3b2c65e323 Import of original zoneinfo code and database - tzcode
old-tzcode-32-bit-output and tzdata2007d.
2007-03-26 10:55:16 +00:00
Ben Gras
5596ab1ec7 Minor corrections by ASW. 2007-03-22 16:24:06 +00:00
Ben Gras
75f8ceb70e let tty do sys_physcopy; needed for loadfont. 2007-03-22 16:15:33 +00:00
Ben Gras
31c62a7347 include svn revision number in <minix/sys_config.h>, printed by kernel
at startup, to easily identify releases.
2007-03-21 13:35:06 +00:00
Ben Gras
70ab580d6b Let user exit without pressing ^C 2007-03-21 09:54:09 +00:00
Ben Gras
bd2ddd5fd4 after enqueue()ing a process, only pick_proc() a new one if the current
process is not PREEMPTIBLE (or it's not ready, or there isn't a current
process yet). This fixes a case where a process that isn't
PREEMPTIBLE actually gets preempted. (This solves a race condition
between CLOCK and SYSTEM.)
2007-03-21 09:45:01 +00:00
Ben Gras
4e63801916 a script to decode stack traces. 2007-03-21 09:33:39 +00:00
Ben Gras
1588a9ba77 slightly more accurate and verbose sanity checking 2007-03-15 10:57:39 +00:00
Ben Gras
98410fd5fe remove extra arg 2007-03-15 10:54:35 +00:00
Ben Gras
5c4a1e5c95 Slightly more flexible packman. 2007-03-12 16:55:02 +00:00
Ben Gras
9843d7a625 For /dev/mem, map in memory to be copied to memory's own address space
one page at a time, and use safecopies to copy it to the requesting
process.

This lets /dev/mem access the entire physical address space, as the minix
page tables only allow access by default to physical RAM, which breaks
e.g. the VESA X driver in some cases.
2007-03-09 16:03:19 +00:00
Ben Gras
f4b7a16f7b output CRLF instead of just LF to serial 2007-03-09 15:45:35 +00:00
Ben Gras
3fcf9fde61 Make /dev/mouse an alias for /dev/kbdaux for X 2007-03-08 16:04:59 +00:00
Ben Gras
6d50591226 . let kernel use read_tsc() from sysutil library
. read_tsc() in sysutil library saves edx and eax now
 . added read_tsc_64() by Antonio Mancina to load tsc into
   a 64-bit data type directly
 . deleted read_tsc.h in favour of a prototype in <minix/syslib.h>
2007-03-08 15:39:14 +00:00
Ben Gras
4148c24393 Russian setup document contributed by Roman Ignatov. 2007-03-08 15:18:57 +00:00
Ben Gras
454bb40129 correct references to manpage section 9 to 1x. 2007-03-05 16:43:03 +00:00
Ben Gras
f8eb059bb9 move manpages in section 9 to new section 1x. 2007-03-05 16:36:40 +00:00
Ben Gras
5f46b37a3d Rename section 9 to section 1x 2007-03-05 16:32:30 +00:00
Ben Gras
97fa05d773 Merge of kjb's update to man system to move section 9 to 1x. 2007-03-05 16:31:39 +00:00
Ben Gras
52b71b2396 Minor change to path lookup that fixes the bug that creating a file
as a first component of an absolute path failed (e.g. 'touch /file'),
due to leading slashes not being skipped in the processed path counter
in that case, causing create to fail.
2007-02-28 13:13:39 +00:00
Ben Gras
84b77d5bfd explicitly mask byte i/o values to bytes. 2007-02-26 11:52:04 +00:00
Ben Gras
8c9e1cf4c5 Uninitialized vector entry? 2007-02-23 20:58:10 +00:00
Ben Gras
92e57afdf3 Explicitly mask off 8-bit values (so new sanity check doesn't trip) 2007-02-23 20:53:32 +00:00
Ben Gras
3b08825d85 . service tells you which device it couldn't stat
. bigger rs and ramdisk for drivers
. sanity check for pv_set macro for oversized arguments
2007-02-23 18:22:46 +00:00
Ben Gras
bf08c90e74 Slew of debugging / sanity check features. 2007-02-23 18:21:19 +00:00
Ben Gras
238ae978ba Don't allow sys_kill to SELF alltogether. 2007-02-23 13:01:55 +00:00
Ben Gras
a9f2f36f46 If a process does sys_kill on SELF (such as in panic() of servers and drivers
if a PM exit fails, until they are compiled with the new panic() function that
is), don't reply to it as the endpoint has been cleared.
2007-02-23 12:55:29 +00:00
Ben Gras
be30a639cd Don't sys_kill SELF if a PM exit fails; just generate a fault to get
us killed through the kernel with PM finding out.

This makes it unnecessary for servers and drivers to be able to do
sys_kill generally, so KILL can go out of /etc/drivers.conf.
2007-02-23 12:54:02 +00:00
Ben Gras
1bf8a2e8bf Changed logic checking for valid device. 2007-02-23 10:21:55 +00:00
Ben Gras
d75a1c3f38 Note about mkfs needing more memory after r2751. 2007-02-23 08:33:33 +00:00
Ben Gras
3bb73b431b add/re-enable at_wini debug output 2007-02-21 17:49:35 +00:00
Ben Gras
2d95b37f12 Copypaste bug. 2007-02-21 17:01:43 +00:00
Ben Gras
77474b28e8 Typo reported by Al Woodhull. 2007-02-21 15:17:28 +00:00
Ben Gras
f7992c94ec at_wini also needs a pci_reserve() for the pci compatability device, if
present, for dma.
2007-02-20 18:42:43 +00:00
Ben Gras
168d766f32 . pci driver now returns devices, even when they have been pci_reserve()d
. pci_reserve() returns an error on devices that have already been reserved,
  instead of panic()ing; the pci_reserve() library call still panics,
  pci_reserve_ok() returns an int.
. this allows at_wini to use the instance value as intended, as all devices
  are seen, even reserved ones
. only devices actually used by at_wini are pci_reserve()d
. pci doesn't release devices based on argv[0], as at_wini both have the
  same name and multiple instances won't work together properly
2007-02-20 17:09:19 +00:00
Ben Gras
825f29fd89 TZ update for new US/Canadian DST rules, fixed by Al Woodhull. 2007-02-20 16:29:26 +00:00
Ben Gras
cbb67705d5 Include svn revision number in iso filename when doing build
based on svn export.
2007-02-19 16:40:33 +00:00
Ben Gras
f150b11a7b Removed args debugging line 2007-02-16 15:58:05 +00:00
Ben Gras
654f6faf05 don't let /dev/mem read beyond top of physical memory 2007-02-16 15:57:05 +00:00
Ben Gras
49d2195722 made default wakeup time correct 2007-02-16 15:56:00 +00:00
Ben Gras
448376ee7e . use library function to parse memory string
. remove unused variables and some other gcc warnings
2007-02-16 15:55:20 +00:00
Ben Gras
3275602598 . made memory parsing function into a library call
(moved 'struct memory' to <minix/type.h> for this library call)
 . removed some debugging messages from pci library
2007-02-16 15:54:28 +00:00
Ben Gras
a47531cc97 removed some verbose messages 2007-02-16 15:53:10 +00:00
Ben Gras
0d5c50f3fc Update CMOS time at shutdown time. 2007-02-16 15:52:39 +00:00
Ben Gras
3f58857ce9 removed/optionalized debugging messages 2007-02-16 15:50:49 +00:00
Ben Gras
b267d42531 removed or optionalized verbose/debugging messages 2007-02-16 15:50:30 +00:00
Ben Gras
1ff8616378 set 'w_testing' during w_identify(). this means 0-tolerance to
timeouts, and an ATA_IDENTIFY timeout will cause the ATAPI_IDENTIFY
to be skipped, making the cd probe a lot faster.
2007-02-12 13:35:33 +00:00
Ben Gras
cb2f124830 mkfs needs more memory for the boot ramdisk. 2007-02-12 13:10:06 +00:00
Ben Gras
bd27c5240b Typo's. 2007-02-12 12:27:43 +00:00
Ben Gras
b857dec78d Don't complain about missing ip address. 2007-02-09 16:28:34 +00:00
Ben Gras
1d300550cf Memory requirements a bit more now with mfs processes 2007-02-09 16:27:59 +00:00
Ben Gras
c6f8154df0 use shorter ata timeout for identify commands when running from cd
to shorten probe time.
2007-02-09 15:58:33 +00:00
Ben Gras
304471a107 Fixes for /usr/xbin binaries bootstrap dir. 2007-02-08 17:41:40 +00:00
Ben Gras
20a13246a8 include /usr/xbin bootstrap dir in $PATH 2007-02-08 16:48:34 +00:00
Ben Gras
9f2f3dd488 don't call mkdep with an absolute path 2007-02-08 16:26:20 +00:00
Ben Gras
df9326a340 Use temporary binary directory as bootstrap 2007-02-08 16:18:48 +00:00
Ben Gras
624f17ee04 Extend cdprobe probe list to c1, and reorder minors to do most-likely
first.

Make at_wini include instance number in error messages.
2007-02-08 15:56:58 +00:00
Ben Gras
ebde52a9bc supply instance to 2nd at_wini instance.
requires a little cooperation from at_wini.
2007-02-08 14:23:03 +00:00
Ben Gras
a12c7ad963 Start a 2nd copy of at_wini, for /dev/c1*. This requires a slightly
larger rs.
2007-02-08 14:04:59 +00:00
Ben Gras
63a271200e Make /dev/c1* device nodes on disk and on the boot ramdisk.
. include c1* nodes in std in MAKEDEV
 . this requires a slightly larger shell
 . this requires a larger blocksize on the boot ramdisk (to fit
   /dev/ in direct blocks for mkfs with a proto file)
 . also more inodes and kB's on the boot ramdisk
2007-02-08 13:51:35 +00:00
Ben Gras
3c907e6ef1 Sanity check in clock - process is supposed to be runnable when it's
interrupted.
2007-02-08 12:59:29 +00:00
Ben Gras
8ea438ae93 Retired DEV_{READ,WRITE,GATHER,SCATTER,IOCTL} (safe versions *_S are to
be used and drivers should never receieve these 'unsafe' variants
any more).
2007-02-07 16:22:19 +00:00
Ben Gras
41e9fedf87 Mostly bugfixes of bugs triggered by the test set.
bugfixes:
 SYSTEM:
 . removed
        rc->p_priv->s_flags = 0;
   for the priv struct shared by all user processes in get_priv(). this
   should only be done once. doing a SYS_PRIV_USER in sys_privctl()
   caused the flags of all user processes to be reset, so they were no
   longer PREEMPTIBLE. this happened when RS executed a policy script.
   (this broke test1 in the test set)

 VFS/MFS:
 . chown can change the mode of a file, and chmod arguments are only
   part of the full file mode so the full filemode is slightly magic.
   changed these calls so that the final modes are returned to VFS, so
   that the vnode can be kept up-to-date.
   (this broke test11 in the test set)

 MFS:
 . lookup() checked for sizeof(string) instead of sizeof(user_path),
   truncating long path names
   (caught by test 23)
 . truncate functions neglected to update ctime
   (this broke test16)

 VFS:
 . corner case of an empty filename lookup caused fields of a request
   not to be filled in in the lookup functions, not making it clear
   that the lookup had failed, causing messages to garbage processes,
   causing strange failures.
   (caught by test 30)
 . trust v_size in vnode when doing reads or writes on non-special
   files, truncating i/o where necessary; this is necessary for pipes,
   as MFS can't tell when a pipe has been truncated without it being
   told explicitly each time.
   when the last reader/writer on a pipe closes, tell FS about
   the new size using truncate_vn().
   (this broke test 25, among others)
 . permission check for chdir() had disappeared; added a
   forbidden() call
   (caught by test 23)

new code, shouldn't change anything:
 . introduced RTS_SET, RTS_UNSET, and RTS_ISSET macro's, and their
   LOCK variants. These macros set and clear the p_rts_flags field,
   causing a lot of duplicated logic like

       old_flags = rp->p_rts_flags;            /* save value of the flags */
       rp->p_rts_flags &= ~NO_PRIV;
       if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);

   to change into the simpler

       RTS_LOCK_UNSET(rp, NO_PRIV);

   so the macros take care of calling dequeue() and enqueue() (or lock_*()),
   as the case may be). This makes the code a bit more readable and a
   bit less fragile.
 . removed return code from do_clocktick in CLOCK as it currently
   never replies
 . removed some debug code from VFS
 . fixed grant debug message in device.c
 
preemptive checks, tests, changes:
 . added return code checks of receive() to SYSTEM and CLOCK
 . O_TRUNC should never arrive at MFS (added sanity check and removed
   O_TRUNC code)
 . user_path declared with PATH_MAX+1 to let it be null-terminated
 . checks in MFS to see if strings passed by VFS are null-terminated
 
 IS:
 . static irq name table thrown out
2007-02-01 17:50:02 +00:00
Ben Gras
fa59af2bc0 Also exclude /home 2007-02-01 17:10:03 +00:00
Ben Gras
047847e628 simpler /usr/bin/vi check 2007-02-01 17:09:49 +00:00
Ben Gras
5358dc42bf Only install /usr/bin/vi as a hardlink to elvis if there's nothing already
there (so e.g. nvi isn't overwritten).
2007-01-31 13:00:39 +00:00
Ben Gras
ce5add84e8 put mfs in /sbin, where mount expects it. 2007-01-24 15:50:04 +00:00
Ben Gras
e8edfe876d . no .vimrc in standard user's dirs
. install a vi hardlink to elvis
2007-01-22 17:08:36 +00:00
Ben Gras
73e4e31376 Don't reply to the caller on RS_DOWN until process is actually dead -
otherwise (e.g.) mounts right after an unmount of the same device don't
work (duplicate label).
2007-01-22 16:44:03 +00:00
Ben Gras
f9e4768eb4 No /usr/src.* shenanigans any more. 2007-01-22 15:47:40 +00:00
Ben Gras
82ae9b9c5c Install sources in /usr/bigsrc, not /usr/src/commands. 2007-01-22 15:42:40 +00:00
Ben Gras
980b58d8d2 ramdisk can be set only once. 2007-01-22 15:37:26 +00:00
Ben Gras
2194bc0310 vfs/mount/rs/service changes:
. changed umount() and mount() to call 'service', so that it can include
   a custom label, so that umount() works again (RS slot gets freed now).
   merged umount() and mount() into one file to encode keep this label
   knowledge in one file.
 . removed obsolete RS_PID field and RS_RESCUE rescue command
 . added label to RS_START struct
 . vfs no longer does kill of fs process on unmount (which was failing
   due to RS_PID request not working)
 . don't assume that if error wasn't one of three errors, that no error
   occured in vfs/request.c
mfs changes:
 . added checks to copy statements to truncate copies at buffer sizes
   (left in debug code for now)
 . added checks for null-terminatedness, if less than NAME_MAX was copied
 . added checks for copy function success
is changes: 
 . dump rs label
drivers.conf changes:
 . added acl for mfs so that mfs can be started with 'service start',
   so that a custom label can be provided
2007-01-22 15:25:41 +00:00
Ben Gras
d954a122f7 Added register clobber warning to read_tsc. 2007-01-22 15:15:30 +00:00
Philip Homburg
78fe72e198 Many more IDs. 2007-01-19 17:27:51 +00:00
Philip Homburg
7d6b1dcf1e PCI IDs for Accton SMC2-1211TX 2007-01-18 11:40:13 +00:00
Ben Gras
a6ab1cbd34 remove debug (%d) in fsck 2007-01-16 16:52:51 +00:00
Ben Gras
722f1b2b9f . added checks for buffer sizes in sys_datacopy() functions in mfs,
print debug message if copy is truncated
. increased buffer in lookup() to be PATH_MAX instead of NAME_MAX
. sanity check in fetch_name() in vfs to see if name fits, and
  is null-terminated
. first check i < NAME_MAX, then string[i] in search_dir, as we're
  not supposed to look at string[NAME_MAX]
2007-01-16 14:50:10 +00:00
Ben Gras
94b936d7c1 . added super-user check for mount
. corrected device match for unmount (otherwise unmount would
  proceed with bogus mount slot, often sending messages to 0 (PM))
. added some sanity checking to fs process number
. made fs_sendrec PRIVATE to request.c
2007-01-16 13:57:35 +00:00
Ben Gras
8412423248 Fsck needs more memory for bigger filesystems 2007-01-16 12:59:13 +00:00
Ben Gras
bcbac65a07 Don't panic if opening a block device fails. 2007-01-12 17:16:51 +00:00
Ben Gras
80e2b3ade6 Truncate s_max_size at LONG_MAX, now that off_t is signed. 2007-01-12 16:53:12 +00:00
Ben Gras
f47aa04a30 . removed readclock command and cmos driver.
. replaced by a readclock 'driver' that runs once, a re-imported version
  of the minix 2.0.4 readclock command.
. this has also restored cmos writing.
. readclock wrapper script calls service command to run /bin/readclock.drv
  once.
2007-01-12 16:35:04 +00:00
Ben Gras
f65b3b8fbf Use bitwise not instead of logical not on PIE flag when disabling periodic
interrupts to avoid clobbering register B. This seems to have fixed the
corrupting-CMOS bug when enabling profiling.
2007-01-12 16:33:41 +00:00
Ben Gras
b01aff70d2 use servers/inet/mq.[ch] to queue messages using mq_queue() in
libdriver.  at_wini now queues messages it can't handle it receives when
waiting for an interrupt. this way it can do receive(ANY) and timeouts
should be working again (were broken for VFS, as with the advent of VFS,
at_wini could get requests from a filesystem while it was waiting for an
interrupt - as a hack, the receive() was changed to receive(HARDWARE)).

Added mq.c to libdriver, and made libdriver an actual library that
drivers link with -L../libdriver -ldriver. (So adding files, if
necessary, is easier next time.)
2007-01-12 13:33:12 +00:00
Ben Gras
8b3ddfc19f In some configurations of non-working networking, packman will hang a
very long time or forever retrieving the packages list. It's tricky to
test connectivity automatically, so ask every time.  Reported by
Stanislav Kapustin <kapustin_stanislav@hotmail.com>.
2007-01-11 14:35:29 +00:00
Ben Gras
f307d84cda Zlib is now an optional package. 2007-01-09 17:08:31 +00:00
Ben Gras
61b9193ced Take arch+version specific packages List file. 2007-01-08 15:10:27 +00:00
Philip Homburg
7d46116e47 ctty command without parameters to disable serial console. 2007-01-08 14:30:11 +00:00
Philip Homburg
9092146be7 VFS cleanup (mostly open). 2007-01-05 16:36:55 +00:00
Ben Gras
753f7bebde Don't let rs232 code send REVIVEs. 2007-01-04 12:06:04 +00:00
Ben Gras
324c6f583d Use svn instead of cvs 2006-12-22 16:43:30 +00:00
Ben Gras
dfaf30e54d interface.h is unused (remainder from Ingmar's work) 2006-12-22 15:50:17 +00:00
Ben Gras
53a6054b66 arch/i386/include/protect.h is unnecessary; add make.conf to etc/ and
note about it in docs/UPDATING.
2006-12-22 15:48:27 +00:00
Ben Gras
6f77685609 Split of architecture-dependent and -independent functions for i386,
mainly in the kernel and headers. This split based on work by
Ingmar Alting <iaalting@cs.vu.nl> done for his Minix PowerPC architecture
port.

 . kernel does not program the interrupt controller directly, do any
   other architecture-dependent operations, or contain assembly any more,
   but uses architecture-dependent functions in arch/$(ARCH)/.
 . architecture-dependent constants and types defined in arch/$(ARCH)/include.
 . <ibm/portio.h> moved to <minix/portio.h>, as they have become, for now,
   architecture-independent functions.
 . int86, sdevio, readbios, and iopenable are now i386-specific kernel calls
   and live in arch/i386/do_* now.
 . i386 arch now supports even less 86 code; e.g. mpx86.s and klib86.s have
   gone, and 'machine.protected' is gone (and always taken to be 1 in i386).
   If 86 support is to return, it should be a new architecture.
 . prototypes for the architecture-dependent functions defined in
   kernel/arch/$(ARCH)/*.c but used in kernel/ are in kernel/proto.h
 . /etc/make.conf included in makefiles and shell scripts that need to
   know the building architecture; it defines ARCH=<arch>, currently only
   i386.
 . some basic per-architecture build support outside of the kernel (lib)
 . in clock.c, only dequeue a process if it was ready
 . fixes for new include files

files deleted:
 . mpx/klib.s - only for choosing between mpx/klib86 and -386
 . klib86.s - only for 86

i386-specific files files moved (or arch-dependent stuff moved) to arch/i386/:
 . mpx386.s (entry point)
 . klib386.s
 . sconst.h
 . exception.c
 . protect.c
 . protect.h
 . i8269.c
2006-12-22 15:22:27 +00:00
Ben Gras
f7984144d5 . fsck needs more memory
. fsck must deal with s_max_file_size in superblock being larger
   than LONG_MAX now that off_t is signed
2006-12-22 13:40:37 +00:00
Philip Homburg
dac2e8fcc9 More detailed upgrade procedure. 2006-12-22 13:36:18 +00:00
Ben Gras
da42185e1c Removed verbose statements from vfs and mfs 2006-12-22 11:54:42 +00:00
Ben Gras
4daf936bd2 BSD versions of strcasecmp() and strncasecmp() after a bug
in strcasecmp() reported by Rogier Meurs <rogier@meurs.org>.
2006-12-19 13:15:16 +00:00
Ben Gras
7d012272a1 make pci driver run as root, so it can call procstat 2006-12-15 15:56:36 +00:00
David van Moolenbroek
d4e6fe3546 Setjmp/longjmp updates and cleanup. 2006-12-08 16:23:18 +00:00
Philip Homburg
170a72fd61 Missing lseek64 library functions. 2006-12-07 20:01:43 +00:00
Philip Homburg
8a2a957d49 Some 64-bit file offset changes that were left out accidentally in the first
commit.
2006-12-06 15:21:27 +00:00
Philip Homburg
bafc45a309 First cut at 64-bit file offsets in block devices for mkfs/fsck. 2006-11-27 14:21:43 +00:00
Philip Homburg
828e87862f Replaced <servers/fs/...> with <servers/mfs/...> 2006-11-24 14:04:01 +00:00
Philip Homburg
d84dd06b3f Better error handling in _mount.c 2006-11-24 14:01:14 +00:00
Philip Homburg
2032e23e8c chmod needs more space 2006-11-24 13:59:13 +00:00
Philip Homburg
0438bca7aa Small image doesn't fit on boot floppy. 2006-11-24 13:57:37 +00:00
Ben Gras
1030187965 Revert back to previous minised 2006-11-17 16:12:08 +00:00
Ben Gras
03be184bd6 Fix warnings (Ingmar Alting) 2006-11-10 18:19:38 +00:00
Ben Gras
f8a5db5ab0 Fix some warnings (by Ingmar Alting) 2006-11-10 18:13:02 +00:00
Philip Homburg
d83e4d3b2e Added missing defines in include/minix/vfsif.h 2006-11-10 15:05:32 +00:00
Philip Homburg
ca448f0b0f Getdents implementation in library/vfs/mfs.
Changed readdir, etc. to use getdents
2006-11-09 16:22:54 +00:00
Ben Gras
12eb228aae Typo reported by ville.solarius@gmail.com 2006-11-06 18:02:22 +00:00
Ben Gras
07c4c00181 set $PATH so /usr/local/egrep isn't used; also exclude /var/log from package 2006-11-03 14:47:28 +00:00
Ben Gras
1250e94d56 New sed manpage 2006-11-02 16:51:04 +00:00
Ben Gras
f6436dc1a0 old sed out, new sed in 2006-11-02 16:48:47 +00:00
Ben Gras
aa8206941c New sed 2006-11-02 16:48:15 +00:00
Ben Gras
64dbdd855d obsolete server. 2006-11-01 16:53:45 +00:00
Philip Homburg
954ad990e5 at_wini now calls pci_reserve. 2006-11-01 14:55:00 +00:00
Ben Gras
86303b3024 Explicit conversion from O_ACCMODE to minix [RW]_BIT is clearer
and catches bogus values (such as 3).
2006-11-01 14:17:47 +00:00
Philip Homburg
0c1d433f60 rs changes (also use driver configurations in the image ramdisk) 2006-10-31 13:35:04 +00:00
Ben Gras
9ac537eb7c Ignore .svn dir as well as CVS dir. 2006-10-30 16:11:57 +00:00
Ben Gras
7195fe3325 System statistical and call profiling
support by Rogier Meurs <rogier@meurs.org>.
2006-10-30 15:53:38 +00:00
Ben Gras
fa0ba56bc9 Merge of VFS by Balasz Gerofi with Minix trunk. 2006-10-25 13:40:36 +00:00
Ben Gras
21ed846479 More memory for these drivers 2006-10-25 13:39:53 +00:00
Ben Gras
65a1d21963 Part of wait()/waitpid() fix in revision 2629:2634 in PM - kernel
unblocks a process that has no priority (stopped with sys_nice()
and PRIO_STOP) and reschedules it if that gives it RTS flags of 0.
2006-10-25 13:38:31 +00:00
Ben Gras
f84653d908 Default amount of memory for tests (some ran out of memory) 2006-10-25 13:35:03 +00:00
Philip Homburg
7c0fda0932 Include kernel/priv.h for rs/manager.h 2006-10-25 13:07:58 +00:00
Ben Gras
1e656b349d . processes stay ZOMBIE, even after wait(), to avoid wrongly seeing them
as living processes  before they are cleaned up (fixes
  wait()/waitpid() hanging forever on previously-ZOMBIE processes)

. stop processes from running using sys_nice() with PRIO_STOP
  when a handled signal is delivered, before computing 
  stack locations for sys_sigsend(). (fixes race condition
  when runnable processes get signals, and e.g. get scheduled
  before FS sends a reply to unpause(), which can make the
  signal stack location wrong.)
2006-10-25 11:29:43 +00:00
Ben Gras
4933f34715 Don't do make clean if flex Makefile doesn't exist. 2006-10-24 14:20:59 +00:00
Philip Homburg
f9ccfca2a1 (Incomplete) support for access control in PCI (pci_set_acl).
-script argument to service for crash recovery scripts
-config argument to service for driver resource configuration
restart command in service to restart a driver after a crash (for use in
crash recovery scripts).
down and refresh now take labels instead of pids.
verious changes in rs to make this work.
2006-10-20 15:01:32 +00:00
Philip Homburg
fd448c332b Access control in do_sdevio and do_vdevio 2006-10-20 14:46:55 +00:00
Philip Homburg
dd3ee082b2 Initialize priv from user supplied priv structure in SYS_PRIV_INIT.
Added SYS_PRIV_USER call to downgrade a privileged process to a user process.
2006-10-20 14:42:48 +00:00
Philip Homburg
1ce2f75627 Additional ptrace commands for fault injection. 2006-10-20 14:14:08 +00:00
Philip Homburg
be928f01a5 Nice(3) implementation 2006-10-20 14:10:53 +00:00
Philip Homburg
0b2c167c48 Bigger ramdisk 2006-10-20 13:59:42 +00:00
Philip Homburg
8082aad9b2 Use /usr/tmp as temp dir for compiling imgrd_s.s 2006-10-20 13:58:45 +00:00
Philip Homburg
61bbef2f4e More stack for the log driver. 2006-10-20 13:54:14 +00:00
Ben Gras
140afcfb7d Use size-dependant no. of words, with OPEN_MAX as default for fd_set size. 2006-10-06 15:45:13 +00:00
Ben Gras
1f3560229d Fix for clean target. 2006-10-06 15:44:41 +00:00
Ben Gras
84c93dd20e Remove objects in aes subdir too 2006-10-05 09:58:50 +00:00
Ben Gras
b5a6e7bbb0 make clean in ibm subdir too 2006-10-05 09:56:17 +00:00
Ben Gras
810de3b474 Leftover junk 2006-10-05 09:55:29 +00:00
Ben Gras
3b295eb002 Don't include this in the distribution. 2006-10-05 09:53:42 +00:00
Ben Gras
cbfa0f4fb8 Change select() so that only as many words as necessary for the 'nfds'
argument from the fd bitmasks are copied from and back to userspace. This
solves an ABI dependency on OPEN_MAX. If nfds is too big for the current
OPEN_MAX, select() fails (but that's relatively easy to fix by 'just'
recompiling the system and not the application binaries), but if it's
smaller, binaries keep working.
2006-10-04 13:28:38 +00:00
Ben Gras
1d4be8052f Don't install progressbar suid. 2006-09-27 15:40:10 +00:00
Ben Gras
b5b76d5691 Reorder for port order, and add svn (Subversion) as service (port 3690) 2006-09-27 13:55:54 +00:00
Ben Gras
c2bbcfe560 _NSIG is supposed to be highest signal number plus one, not highest
signal number.
2006-09-27 08:56:37 +00:00
Philip Homburg
d9bfb27282 Missing negation in comment 2006-09-21 13:33:23 +00:00
Philip Homburg
d24a880003 Added EOPNOTSUPP and better error handling in accept. 2006-09-14 13:48:41 +00:00
Philip Homburg
c39a693274 Disabled /etc/rc.rescue 2006-09-08 13:20:57 +00:00
Philip Homburg
4cc6be8532 NUL terminate timingdata[cat].names instead of timingdata[0].names. Reported
by <devel@pop3.ru>.
2006-08-28 15:30:14 +00:00
Philip Homburg
3e35db1514 Also clear word 6 in the ATAPI SCSI_READ10 command packet (in atapi_transfer). 2006-08-28 15:10:10 +00:00
Philip Homburg
f6c4002b35 first commit of extra ptrace code for fault injection. 2006-08-28 15:03:03 +00:00
Philip Homburg
c5efbf71c0 first commit of extra ptrace code for fault injection 2006-08-28 14:59:56 +00:00
Philip Homburg
62cb625f1b Removed superfluous assignment to text_base. Reported by Ildar Ismagilov. 2006-08-28 14:59:55 +00:00
Philip Homburg
d68627f3a8 No need for .depend files in CVS. 2006-08-28 14:32:24 +00:00
Philip Homburg
66f9a5f508 Do not abort/panic when an ethernet driver does something unexpected. 2006-08-28 12:59:36 +00:00
Philip Homburg
0ac9521c94 TTY should not panic when it is impossible to reply. A driver may crash
before receiving the reply from TTY.
2006-08-28 12:16:15 +00:00
Ben Gras
2f58281a20 New UPDATING file with hints for source updating. 2006-08-18 16:18:54 +00:00
Ben Gras
8ecf9cb9b8 Undo configure script regeneration - not using --libdir 2006-08-18 16:16:06 +00:00
Ben Gras
32f8abc362 Installing in build file sidesteps problems installing as bin 2006-08-17 14:21:10 +00:00
Ben Gras
150a68c940 set $PATH to avoid (e.g.) /usr/local/bin/grep (gnu grep) being found
which has unexpected return codes compared to minix grep.
2006-08-17 14:03:06 +00:00
Ben Gras
b90b5898e4 Let installing work as bin 2006-08-17 10:10:42 +00:00
Ben Gras
cdfe90a6ca Fixes to build and install flex as bin. 2006-08-17 09:53:26 +00:00
Ben Gras
bf195531b3 new command 'dumpcore' that can write core files of running processes. 2006-08-15 15:59:38 +00:00
Ben Gras
5a6052119f Force yacc to be /usr/bin/yacc, in case someone has /usr/local/bin/yacc
(bison) before /usr/bin/yacc in $PATH
2006-08-15 15:59:04 +00:00
Ben Gras
8f7876b1d1 /usr/local/gnu removed as prefix; gcc libs go into /usr/local/lib/gcc now 2006-08-15 15:58:24 +00:00
Ben Gras
87f95d7c02 No separate beta dir 2006-08-15 15:57:13 +00:00
Ben Gras
a178a15950 Make packman minix-version-aware 2006-08-15 15:56:42 +00:00
Ben Gras
030d4a7e2c add xxl to usage
don't touch non-compiler binaries
2006-08-15 15:56:09 +00:00
Ben Gras
1d7257b613 Code for 'service run' 2006-08-15 15:55:04 +00:00
Ben Gras
b888922d62 Added 'service run' to run a service without restart. 2006-08-15 15:54:51 +00:00
Philip Homburg
82a5bffa7d Pass 'service' instead of 'argv[1]' to servxcheck. 2006-08-10 14:13:28 +00:00
Philip Homburg
6076eddf9c Use syslog for logging. 2006-08-10 14:11:25 +00:00
Ben Gras
4539e54d8b . fix for wild store at startup time by calling dev_io without fp
initialized
 . fix for writing exactly PIPE_SIZE to a pipe with O_NONBLOCK blocking
   anyway because of incomplete logic in pipe_check
2006-08-10 11:51:11 +00:00
Philip Homburg
4ba5826ba6 Improved access checks in system.c. Grant drivers and FS the rights they need. 2006-08-10 10:56:16 +00:00
Ben Gras
c3c08d252c report driver source of grant mismatch 2006-08-04 13:31:06 +00:00
Ben Gras
4c7c64cd66 Clarify du units. 2006-08-04 13:26:05 +00:00
Ben Gras
e3ffd4c2b1 Start calling it 3.1.3rc1 2006-08-04 12:12:06 +00:00
Ben Gras
9d9e14941e At least 8k stack for all drivers so that malloc() works, for grants,
for printf().
2006-08-02 22:51:47 +00:00
Ben Gras
23e1bffd7a lance needs 8k in order for safecopies to work (malloc()). 2006-08-02 22:42:10 +00:00
Ben Gras
6dbca44030 Turn off prototypes for readv and writev until they're defined
(properly) in the library.
2006-08-02 15:18:49 +00:00
Ben Gras
5d8c07b3f2 Fix by Joren for setjmp to not clobber %ebx. 2006-08-02 12:03:02 +00:00
Ben Gras
bc8b79da53 Make includes for gcc 4.1.1 too if found. 2006-08-01 09:17:43 +00:00
Ben Gras
636b368dd0 Actually make top suid root 2006-07-31 15:06:53 +00:00
Ben Gras
153e2c406c make top suid root to do getsysinfo. 2006-07-31 14:37:56 +00:00
Ben Gras
99644bed66 /usr/local/src for easypack-fetched sources. 2006-07-31 11:40:14 +00:00
Ben Gras
18327f02a8 Introduced unprivileged getsysinfo variant, to retrieve harmless data
in formats that don't change (or is upwards compatible).
2006-07-27 16:23:01 +00:00
Ben Gras
4d7f2af576 big for big commands 2006-07-27 16:05:17 +00:00
Ben Gras
a284f55473 Bigger bigsh for gcc and binutils 2006-07-27 08:51:08 +00:00
Ben Gras
36e9a43109 Force minix install 2006-07-26 14:26:26 +00:00
Ben Gras
4a6cd8f878 Make ps suid root instead of sguid kmem. This makes getsysinfo
work for it.
2006-07-26 11:34:26 +00:00
Philip Homburg
baa3ac5853 Fix for 'cleanup: not idle: 2313' bug. 2006-07-25 14:13:09 +00:00
Ben Gras
13d1de5122 Taught log driver to return REP_IO_GRANT on revive events, makes revive
work again.
2006-07-25 11:01:54 +00:00
Ben Gras
82173212ee Introduction of a 'big' ioctl, with more bits (20) reserved for encoding the
size field. The TIOCSFON ioctl size (8192) didn't get encoded properly,
as there weren't enough bits for it (12) in the regular format.

The new format has only one type field, and an extra flag (_IOC_BIG)
turned on. FS checks for this flag and uses the alternative decoding
of the ioctl codes to determine the size when doing grants.

This unbreaks loadfont, although that still uses a phys copy in tty.
2006-07-25 09:41:40 +00:00
Ben Gras
7573c41657 flex build fix - can't build and install separately with two different
compilers.
2006-07-25 09:39:13 +00:00
Ben Gras
ec4223d96a More stack for system. 2006-07-25 09:38:24 +00:00
Ben Gras
e6076e2c95 Don't give an error message for usage. 2006-07-24 13:27:17 +00:00
Philip Homburg
61337d5f7b Allow holes in executables. 2006-07-24 13:07:25 +00:00
Ben Gras
0020ad8ac7 Make /usr/local/lib/{ack,gcc} for ack and gcc format libraries. 2006-07-21 16:09:05 +00:00
Ben Gras
75267305f1 distclean first, then install 2006-07-21 14:56:23 +00:00
Ben Gras
deca72b814 Only install. 2006-07-21 14:55:33 +00:00
Ben Gras
cbfcdcc4c2 Use grant address type in loadfont ioctl. 2006-07-21 14:39:48 +00:00
Ben Gras
f7c36e31e5 More stack for env to build g++. 2006-07-21 12:51:56 +00:00
Ben Gras
53cbd9acbf Manpage bug fix reported by Matej Kosik. 2006-07-21 11:19:32 +00:00
Ben Gras
6c7004423d Fix for %#02x bug (shouldn't print 0x, but junk was printed) found by
Joren l'Ami.  Also fixes %p when arg is 0 (printed 0 instead of 0x0).
2006-07-21 10:08:47 +00:00
Philip Homburg
f6d1f6fdf6 Switch to vc 0 and softscrolling when /dev/video is opened and switch back
at the close. This should prevent problems with X on (emulated) Cirrus
cards.
2006-07-19 11:50:18 +00:00
Ben Gras
0d9976ae9f Don't call X 'X Windows'. 2006-07-19 10:51:30 +00:00
Ben Gras
2bb759206f Build gcc library of libfl. 2006-07-18 14:52:53 +00:00
Ben Gras
4033ccc08d 'zmodem' is 'big'. remove unused bits from autopart. This unbreaks
the commands build.
2006-07-17 17:05:54 +00:00
Philip Homburg
59830eda3f Prototypes for send and recv. Fixed send (pass null address) and sendto
(fail when a null address is passed to a socket that is not connected).
2006-07-14 14:34:00 +00:00
Philip Homburg
371ac29c9f Clear NONBLOCK flag after probing ethernet device. 2006-07-14 13:35:21 +00:00
Philip Homburg
ee46e92dd2 Fixed ruserok not to required /etc/hosts.equiv. 2006-07-14 12:48:01 +00:00
Ben Gras
b0fc01eb82 <minix/ds.h> - ds definitions. 2006-07-14 12:40:32 +00:00
Philip Homburg
8f19ca2039 More stack for in.rshd. 2006-07-14 11:22:37 +00:00
Ben Gras
3512a86b44 . DS understands publishing and subscribing where keys are in string
form. Subscriptions are regular expressions.
 . different types are stored per key; currently u32 and/or string.
   the same key can be referenced (publish, subscribe, check) as any type.
 . notify()s are sent when subscriptions are triggered (publishing or
   updating of matching keys); optionally, a subscribe flag sends
   updates for all matching keys at subscription time, instead of only
   after updates after subscribing
 . all interfacing to ds is in /usr/src/lib/syslib/ds.c.
 . subscribe is ds_subscribe
   publish functions are ds_publish_<type>
   retrieve functions are ds_retrieve_<type> (one-time retrieval of a value)
   check functions are ds_check_<type> (check for updated key caller
      subscribes to not yet checked for, or ESRCH for none)
 . ramdisk driver updated with new ds interface
2006-07-13 14:50:23 +00:00
Philip Homburg
d40007667c Do not report non-safe sys_sdevio calls when the address is 'SELF' 2006-07-13 14:46:53 +00:00
Philip Homburg
c06bc3ead8 Left consistency checks enabled in INET in the previous commit. 2006-07-13 13:25:55 +00:00
Philip Homburg
04b478f177 More stack for tcpd.
Safecopies renders the NWIOQUERYPARAM ioctl useless. This functionality
is now replaced with /dev/ipstat. Write the request to the device and
read the answer in one read request.
2006-07-13 13:19:48 +00:00
Ben Gras
2d79ae7831 When installing in a free partition larger than the maximum, don't align
on cylinder boundary.
2006-07-13 12:43:47 +00:00
Ben Gras
b52a516521 Joren's proposed fix for a too-conservative split point selection.
(Making building packages with long filenames difficult.)
2006-07-10 15:05:33 +00:00
Philip Homburg
9939089dea Safecopy support for INET. 2006-07-10 12:55:33 +00:00
Philip Homburg
7ce17fe655 Support for SI_CALL_STATS (counting systemcalls). 2006-07-10 12:44:43 +00:00
Philip Homburg
2cf649db2e Safecopy support in ethernet drivers. 2006-07-10 12:43:38 +00:00
Philip Homburg
9392742cc4 Use safecopy version to get log messages from TTY. 2006-07-10 12:42:31 +00:00
Philip Homburg
fd62815e73 Fixed a bug that would report a device more than once. Added safecopy
version of do_dev_name and do_slot_name.
2006-07-10 12:39:54 +00:00
Philip Homburg
ee09d50403 Changed to use sys_readbios to get screen parameters. Added safecopy version
to get log messages.
2006-07-10 12:37:39 +00:00
Philip Homburg
a3fce7ce8d Changed to use sys_readbios get the 'machine ID'. 2006-07-10 12:35:55 +00:00
Philip Homburg
dcb7cae67c Changed to use sys_readbios to get BIOS parameters. 2006-07-10 12:34:41 +00:00
Philip Homburg
6f4091eb8c Added do_readbios. Added debugging output for unexpected use of unsafe copy
functions.
2006-07-10 12:27:26 +00:00
Philip Homburg
73e5de6354 Added sys_readbios.
Changed pci_dev_name and pci_slot_name to use safecopies.
Mae it possible to disable the use of safecopies in kputc for debugging.
2006-07-10 12:17:16 +00:00
Philip Homburg
d7174ec0ab Added SI_CALL_STATS and ENABLE_SYSCALL_STATS for system call statistics.
Added BUSC_PCI_DEV_NAME_S and BUSC_PCI_SLOT_NAME_S to support safecopies in PCI.
Added DL_WRITEV_S, DL_READV_S, DL_GETSTAT_S, DL_GRANT, and iovec_s_t to support
safecopies in ethernet drviers. Renamed DL_INIT to DL_CONF, and DL_INIT_REPLY
to DL_CONF_REPLY.
Added SYS_READBIOS and sys_readbios to read from BIOS data areas.
Added GET_KMESS_S for safecopy support in LOG.
Added sys_safe_insb and sys_safe_outsb.
2006-07-10 12:13:29 +00:00
Ben Gras
cac387bc1e Clean ramdisk image .s too 2006-07-06 14:09:54 +00:00
Ben Gras
5c55d94007 Bigger BUFSIZ for bigger fs block size. 2006-07-06 10:02:25 +00:00
Ben Gras
1561067ee4 Grant system dynamic-only. 2006-06-30 14:40:29 +00:00
Ben Gras
b654c02f55 Give pm its own brk() so malloc() works in pm. pm needs more stack for this. 2006-06-30 14:36:11 +00:00
Ben Gras
b5179d7025 Split do_brk in a stub and a function that does the real work, so that
the real work can be called from elsewhere too. Specifically, to allow PM
its own brk().
2006-06-30 14:35:38 +00:00
Ben Gras
0323892f71 3rd fix for improper behaviour on crashing driver with safe_io_conversion 2006-06-29 14:24:07 +00:00
Ben Gras
407eefe63a Compile fix 2006-06-29 14:23:33 +00:00
Ben Gras
f1222a09a6 Make stack traces on exceptions possible. 2006-06-29 13:35:27 +00:00
Ben Gras
bfca7d68ba Fix another bug related to trying i/o more than once 2006-06-28 12:20:30 +00:00
Ben Gras
46646a49a8 Don't print cloexec 2006-06-28 10:04:32 +00:00
Ben Gras
f9fb0ff546 Fix bug where safe conversion doesn't happen after 1st time in loop 2006-06-28 10:03:18 +00:00
Ben Gras
6b1f8de38a Added _select() stub for select(). 2006-06-27 18:28:33 +00:00
Ben Gras
bd535a120b . satisfy some gcc warnings (uninitialized/unused variables)
. change cloexec mask from long to fd_set to remove 32 fd's per
   process restriction (from cloexec at least)
2006-06-27 16:47:35 +00:00
Ben Gras
a0f8161fe7 Stopgap for tar creating insane group ownerships due to tiny gid_t. 2006-06-27 16:30:46 +00:00
Ben Gras
59bedc2074 let dynamic allocation of table work 2006-06-27 14:15:47 +00:00
Ben Gras
607fb6bf7f Add a flag to grants system indicating a slot is VALID; so a slot
can be reserved (USED), while toggling VALID on and off.
2006-06-27 12:19:45 +00:00
Ben Gras
a587273c56 . expanded grant manipulation interface to more direct
manipulation
. made fs allocate a grant for every ioctl, even if no data
  is being copied, in order to disambiguate concurrent ioctls
  on the same minor
2006-06-26 16:08:42 +00:00
Philip Homburg
2f50f92eb3 Move inet to safe copies. 2006-06-26 16:03:35 +00:00
Ben Gras
961a173573 Fix to let elle understand window size. 2006-06-26 15:15:40 +00:00
Philip Homburg
de07a562d1 Vectored safe copies for inet. 2006-06-26 14:20:11 +00:00
Philip Homburg
14c9743ecf First cut at safe copies for inet. Breaks tcpstat. 2006-06-26 11:17:19 +00:00
Ben Gras
48a6203ae7 A backup of the readclock command that shouldn't have been imported into cvs. 2006-06-26 08:58:11 +00:00
Ben Gras
3b814d36d1 Rename paramctl to setgrant. 2006-06-23 15:35:05 +00:00
Philip Homburg
add4be444f get_sys_bits 2006-06-23 15:32:24 +00:00
Ben Gras
002922fa4c New kernel call, SYS_PARAMCTL, that sets parameters of the caller
and is therefore unprivileged. Used to set grant tables.
2006-06-23 15:07:41 +00:00
Philip Homburg
8dfac43a75 Print ipc_to in hex. Also print the 'system' call mask. 2006-06-23 13:27:03 +00:00
Ben Gras
777dbbe3f7 Everyone's endpoint number 2006-06-23 12:16:22 +00:00
Ben Gras
0e9c6932c4 use malloc() + copy + free() instead of realloc() 2006-06-23 12:07:41 +00:00
Ben Gras
3ffa1684ae New option -E for ps that prints endpoint numbers instead of pids. 2006-06-23 11:59:20 +00:00
Ben Gras
31318a8ce5 library interface for vectored safecopy variant. 2006-06-23 11:54:35 +00:00
Ben Gras
d402047222 Added vectored variant of sys_safecopy*. 2006-06-23 11:54:03 +00:00
Ben Gras
82855e9cf5 . leave out dead code from device.c
. don't loop doing a receive() after sendrec() - chance of recovering is not
  high, and can lead to receive()ing a notify() (which can't happen in sendrec()),
  which is terrible
. return status from device when DEV_CANCEL is done on a signal; hardcode EAGAIN to
  become EINTR though
2006-06-23 11:51:56 +00:00
Philip Homburg
08bb0f7708 No longer build Michael Temari's httpd. Install a httpd from ports. 2006-06-22 11:53:03 +00:00
Philip Homburg
529ca8a4df Added strlcat and strlcpy. 2006-06-22 11:47:18 +00:00
Philip Homburg
bd783b901f Added prototype for inet_aton. 2006-06-22 11:45:59 +00:00
Philip Homburg
20a9ca246d Added __minix3 to make it easier to figure out that we are compiling on/for
Minix 3.
2006-06-22 11:44:17 +00:00
Ben Gras
ed9be75384 <minix/safecopies> 2006-06-20 14:25:42 +00:00
Ben Gras
7b6a1e5f59 More space for rs 2006-06-20 10:59:45 +00:00
Ben Gras
0d39b17655 Changed order of -lsys and -lsysutil for printf() 2006-06-20 10:50:29 +00:00
Ben Gras
705f1039d9 order changed for printf() 2006-06-20 10:47:25 +00:00
Ben Gras
cef426ee54 There is no lex. 2006-06-20 10:14:25 +00:00
Ben Gras
848b96a9a4 Fixes for usb and bios. 2006-06-20 10:13:56 +00:00
Ben Gras
223a0e7b60 Fix for KERNEL definition. 2006-06-20 10:13:32 +00:00
Ben Gras
150c964b49 Fix for losing REVIVE 2006-06-20 10:12:30 +00:00
Ben Gras
2384a85296 FS support for grant-based i/o.
For character device i/o, FS does a so-called 'magic' grant to let the
driver copy from or to user space. As this is done in FS address space,
the driver is told to do this in FS address space. The redirection to
the right user process then happens at copy-time in the kernel, using the
FS grant table. This also happens for DEV_READ and DEV_WRITE on block
devices.

For other block device i/o, which happens from/to FS buffers, FS does
a 'direct' grant to its own address space for the driver.

After the i/o returns, this access has to be K-I-L-L-E-D, revoked.
Sometimes this is after a SUSPEND and DEV_REVIVE, in which case the
revoking happens in pipe.c.

This conversion happens in safe_io_conversion() in device.c, called
by dev_io and dev_bio.

FS has to pre-allocate its own space for these grant tables. This happens
in main.c.
2006-06-20 10:12:09 +00:00
Ben Gras
54f1e6d3d4 Use endpoint_t 2006-06-20 10:04:33 +00:00
Ben Gras
7a76a7a495 Rename protected to prot
Also print size of grant table known in system
2006-06-20 10:03:48 +00:00
Ben Gras
3061d7b17a Changed do_devio not to require DIO_TYPE, but to extract type
from DIO_REQUEST. Also do_vdevio. Also do_sdevio, but this
function also supports grant id's and offsets.

do_segctl: rename protected to prot.

do_umap: support for GRANT_SEG umap.

do_privctl: support SYS_PRIV_SET_GRANTS, which sets location and size
of in-own-address-space grant table.

do_safecopy: functions to verify and perform 'safe' (grant-based) copies.
2006-06-20 10:03:10 +00:00
Ben Gras
ada6592af9 Prototype of do_safecopy 2006-06-20 09:59:50 +00:00
Ben Gras
bf6fa2acd0 Introduced global sys_call_code to check in called kernel call
implementation functions.

Changed check in system.c to check compile-time-sized bitmap of
kernel calls.

Added SYS_SAFECOPYFROM and SYS_SAFECOPYTO, both mapping to
do_safecopy (that's what sys_call_code is used for).
2006-06-20 09:58:58 +00:00
Ben Gras
b89c6634f5 Use endpoint_t. New prototypes for related to grants and safecopy functions. 2006-06-20 09:57:00 +00:00
Ben Gras
2e89eb5270 Change allowed kernel call bitmap to an array of bitmaps to allow
any number of kernel calls.

Allowed kernel calls are stored in table.c for every image process as a
variably-sized array of allowed calls. This is used to fill the bitmap
of size determined at compile time by the number of kernel calls. This
filling is done by main.c. There is a special call called SYS_ALL_CALLS
which fills the bitmap of allowed calls completely, if that is the only
entry in the array.
2006-06-20 09:56:06 +00:00
Ben Gras
eecb40cf21 Rename protected to prot for g++ 2006-06-20 09:52:11 +00:00
Ben Gras
28950e6104 Use endpoint_t type 2006-06-20 09:51:49 +00:00
Ben Gras
831bc7ecd1 Move bitmap manipulation macros to <minix/bitmap.h> 2006-06-20 09:50:26 +00:00
Ben Gras
281e76364a Conversion to safe calls, and returning grant in DEV_REVIVE messages 2006-06-20 09:49:02 +00:00
Ben Gras
d61715a69e Fix for new *_ins* i/o functions 2006-06-20 09:48:26 +00:00
Ben Gras
6d8fa97233 Kick out REVIVE 2006-06-20 09:47:23 +00:00
Ben Gras
b80626c878 safe conversion 2006-06-20 09:46:57 +00:00
Ben Gras
1c8b206a5d . Safe I/O, ioctl() and DIAGNOSTICS variants conversion - safe copies,
include grant id in DEV_REVIVE messages.
. Removal of TTY_FLAGS field (and so O_NONBLOCK support).
. Fixed CANCEL behaviour and return code on blocking I/O,
  previously handled by O_NONBLOCK
. Totally removed REVIVE replies, previously still possible on
  blocking ioctls (REVIVE directly called) and ptys (missing TTY_REVIVE
  check), removes deadlock bug with FS
. Removed obsolete *COMPAT options and associated code
2006-06-20 09:02:54 +00:00
Ben Gras
9fa06d5e3f safe conversion 2006-06-20 08:56:58 +00:00
Ben Gras
5350645c86 Safe I/O and ioctl functions 2006-06-20 08:56:15 +00:00
Ben Gras
60bbcab13f Understand *_S variants: DIAGNOSTICS_S, DEV_{READ,WRITE,IOCTL}_S,
include grant id in DEV_REVIVE messages
2006-06-20 08:55:35 +00:00
Ben Gras
3ca26c812d Change to 'safe' copy variant 2006-06-20 08:54:22 +00:00
Ben Gras
ad6d8a53c8 Understand *_S variants 2006-06-20 08:52:26 +00:00
Ben Gras
4fa6691106 Change for safe copies, and DEV_REVIVE message including grant id 2006-06-20 08:52:11 +00:00
Ben Gras
3bd3c2cee1 Change at driver to understand 'safe' transfers and ioctls; do corresponding
safe copy and safe sys_insw and sys_outsw calls.
2006-06-20 08:51:24 +00:00
Ben Gras
e929676268 . made libdriver understand *_S variants
. ioctl, transfer and 'other' functions get an extra parameter: 'safe', int
  is nonzero if function is called with *_S variant ('other' if ioctl)
2006-06-20 08:49:51 +00:00
Ben Gras
9be69be836 . flex moved back into the base system, so prefix is /usr
. sysenv.c and umount.c need <minix/type.h> now
2006-06-20 08:46:45 +00:00
Ben Gras
296a0fb33d /CD check unnecessary 2006-06-20 08:46:09 +00:00
Ben Gras
9df1183b94 . removed const from putenv() for g++
. added safecopies.c:
  these are library functions to maintain grant tables in own address space
. sys_safecopy.c:
  interfaces to kernel calls to perform safe copy functions in from or to
  foreign process
. changes in i/o fields (type merged with request) reflected in
  library functions (sys_out.c, sys_vinb.c, sys_vinl.c, sys_vinw.c,
  sys_voutb.c, sys_voutl.c, sys_voutw.c)
. type merged with request in sys_sdevio, also now accepts offset which
  is used when a grant is specified (the _DIO_SAFE subtype)
. system printf() function changed to send DIAGNOSTICS_S messages, which
  specify a grant id instead of a direct address for the buffer to be
  printed; tty and log can then safecopy the buffer
2006-06-20 08:45:04 +00:00
Ben Gras
cfb984e9bd . renamed __str to __makestr to allow for g++
. changed some CMOS ioctl codes to have correct sizes (struct tm instead
  of u32_t), a disk ioctl code from W to RW, and memory ioctl codes from R
  to W, needed for proper matching of grant in FS
2006-06-20 08:40:26 +00:00
Ben Gras
aaca17c36d . introduced DEV_READ_S, DEV_WRITE_S, DEV_SCATTER_S, DEV_GATHER_S
and DEV_IOCTL_S as replacements for DEV_READ, DEV_WRITE, DEV_SCATTER,
  DEV_GATHER and DEV_IOCTL. Instead of a direct address, the *_S commands
  pass 'grant ids' to the drivers which are referenced through a new set
  of copy calls (sys_safecopyfrom and sys_safecopyto). in order for this
  copy to succeed, the grant must have previously been created in the
  address space of the granter.
. bitmap manipulation functions moved to <minix/bitmap.h>
. HIGHPOS introduced as field containing high 32 bits of position in
  device I/O message; TTY_FLAGS no longer used
. IO_GRANT field introduced for GRANTs, to replace ADDRESS
. REP_IO_GRANT field for un-SUSPEND messages introduced to indicate
  grant for which I/O was done to disambiguate messages
. SYS_SAFECOPYFROM and SYS_SAFECOPYTO introduced as new calls
. SYS_PRIV_SET_GRANTS code introduced as a code to set the address and
  size of the grant table in a process' own address space
. 'type' and 'direction' field of _ins* and _outs* I/O functions
  are merged into one by ORing _DIO_INPUT/_DIO_OUTPUT and _DIO_BYTE/_DIO_WORD
  etc. This allows for an additional parameter, _DIO_SAFE, which indicates
  the address in another address space isn't actually an address, but
  a grant id. Also needs an offset, for which fields had to be merged.
. SCP_* are field names for SYS_SAFECOPY* functions
. DIAGNOSTICS and GET_KMESS moved to their own range above DIAG_BASE,
  added DIAGNOSTICS_S which is a grant-based variant of DIAGNOSTICS
. removed obsolete BINCOMPAT and SRCCOMPAT options
. added GRANT_SEG type for use in vircopy - allows copying to a grant
  id (without offset)
. added _MINIX_IOCTL_* macros that decode information encoded by
  _IO* macros in ioctl codes, used to check which grants are necessary
  for an ioctl
. introduced the type endpoint_t for process endpoints, changed some
  prototypes and struct field types to match
. renamed protected to prot for g++
2006-06-20 08:38:15 +00:00
Ben Gras
6ef5aa4fb2 . flex back into the base system
. imports of Michael Temari's httpd and ftp
2006-06-19 14:58:20 +00:00
Ben Gras
aa5efff203 Initial revision 2006-06-19 14:55:09 +00:00
Ben Gras
ede3e5ab83 Al Woodhull's new manual pages 2006-06-19 14:51:41 +00:00
Philip Homburg
3edf4c2854 Prototype for readline. 2006-06-14 13:19:48 +00:00
Philip Homburg
a617a46e35 Retry read after EINTR. 2006-06-14 13:18:53 +00:00
Philip Homburg
221e731e45 Wake up writer when selecting for read on an empty pipe.
Set fp_revived to NOT_REVIVING when decrementing reviving.
2006-06-14 13:17:41 +00:00
Philip Homburg
474d137c39 Forgot include some Minix 3 specific changes. 2006-06-07 15:03:42 +00:00
Philip Homburg
cb02a90b77 Fixed some select bugs related to pipes. Removed SELFD_* because they were
bogus and unused.
2006-06-07 14:41:47 +00:00
Philip Homburg
373ea53510 A bigger ramdisk is needed for the new version of ash. 2006-06-07 14:39:50 +00:00
Philip Homburg
acebf7b52f Important BSD version of setenv, added killpg, replaced _sigsetjmp.c with
an assembler jump to longjmp.
2006-06-07 14:38:39 +00:00
Philip Homburg
3f297ffd9f Added killpg to signal.h, rearranged getloadavg, putenv, and setenv in
stdlib.h and added unsetenv, added declaration of optreset to unistd.h.
2006-06-07 14:36:35 +00:00
Philip Homburg
eaf9e4cff8 Make sure that line editing is disabled when the shell is not connected to a
tty.
2006-05-29 13:20:28 +00:00
Philip Homburg
43d9263589 Parsing of '-OT' and '-OS' failed in acd.descr. 2006-05-29 12:29:25 +00:00
Philip Homburg
5f19e53afb Install /usr/lib/descr from the source tree. 2006-05-29 12:25:44 +00:00
Philip Homburg
7aa4c9ec2f New version of ash. From FreeBSD 5.4 via Minix-vmd. 2006-05-23 12:59:34 +00:00
Philip Homburg
3ea083b8d4 Actually remove allocmem and freemem sources from the library. 2006-05-19 12:45:55 +00:00
Philip Homburg
e9aabcf2f8 Disabled building rescue driver (no longer needed). Moved allocmem from
library to the memory driver. Always put output from within TTY directly on
the console. Removed second include of driver.h from tty.c. Made tty_inrepcode
bigger. First step to move PM and FS calls that are not regular (API)
system calls out of callnr.h (renumbered them, and removed them from the
table.c files). Imported the Minix-vmd uname implementation. This provides
a more stable ABI than the current implementation. Added a bit of security
checking. Unfortunately not nearly enough to get a secure system. Fixed a
bug related to the sizes of the programs in the image (in PM patch_mem_chunks).
2006-05-19 12:19:37 +00:00
Philip Homburg
c3cf4ef460 Fixed off by one error in backoff code. Limit backoff to 1 second for
disk drivers.
2006-05-15 12:08:43 +00:00
Philip Homburg
c9ff3994f1 Unpause requests (to FS) can be generated in parallel to other requests. 2006-05-15 12:06:19 +00:00
Philip Homburg
f0186f4179 Do not unmap a driver when the driver dies (it interferes with restarting
disk drivers). Fixed accounting for REVIVING/reviving.
2006-05-15 11:43:06 +00:00
Philip Homburg
ae92cc208d The new service command managed to escape. 2006-05-11 15:30:56 +00:00
Philip Homburg
14b7a72ba3 Init need more space (the results of removing the special case for init in
adjust in PM). Better flags dump in IS.
2006-05-11 15:00:46 +00:00
Philip Homburg
e4967b06bb Special code for restarting disk drivers (-c flag in service). 2006-05-11 14:58:33 +00:00
Philip Homburg
773844a816 New interface between PM and FS. 2006-05-11 14:57:23 +00:00
Philip Homburg
94717cb74c Pass -c flags to service for disk device drivers. 2006-05-11 14:53:20 +00:00
Philip Homburg
aeb6630868 Ignore SIGHUP in floppy driver. 2006-05-11 14:52:40 +00:00
Philip Homburg
15b8fe54a8 Better initialization of the memory map of processes that are part of the
image. Removed NO_MAP flag.
2006-05-11 14:49:46 +00:00
Philip Homburg
71917d6383 Changes for restarting disk drivers and new interface between PM and FS. 2006-05-11 14:47:31 +00:00
Ben Gras
5a8315cf5b call cons_stop() before sys_abort() to not break tty on shutdown 2006-05-11 14:01:44 +00:00
Philip Homburg
5a3d6ac67f Balance curly braces. 2006-05-10 15:39:52 +00:00
Ben Gras
244786ae34 Fix for service formatting bug reported by Jaap Weel <weel@ugcs.caltech.edu> 2006-05-08 22:04:05 +00:00
Ben Gras
461a4fafb1 Added fchmod() and fchown() 2006-04-18 11:26:04 +00:00
Ben Gras
b1e5779b1c *** empty log message *** 2006-04-13 18:12:33 +00:00
Ben Gras
3aedf32a8a *** empty log message *** 2006-04-13 18:07:42 +00:00
1541 changed files with 162623 additions and 186712 deletions

View File

@@ -18,6 +18,7 @@ char version[]= "2.20";
#include <string.h>
#include <errno.h>
#include <ibm/partition.h>
#include <ibm/bios.h>
#include <minix/config.h>
#include <minix/type.h>
#include <minix/com.h>
@@ -28,6 +29,7 @@ char version[]= "2.20";
#if BIOS
#include <kernel/const.h>
#include <kernel/type.h>
#include <sys/video.h>
#endif
#if UNIX
#include <stdio.h>
@@ -46,6 +48,12 @@ char version[]= "2.20";
#define arraylimit(a) ((a) + arraysize(a))
#define between(a, c, z) ((unsigned) ((c) - (a)) <= ((z) - (a)))
int serial_line = -1;
u16_t vid_port; /* Video i/o port. */
u32_t vid_mem_base; /* Video memory base address. */
u32_t vid_mem_size; /* Video memory size. */
int fsok= -1; /* File system state. Initially unknown. */
static int block_size;
@@ -590,6 +598,19 @@ void initialize(void)
bootdev.name[5] += bootdev.secondary;
}
/* Find out about the video hardware. */
raw_copy(mon2abs(&vid_port), VDU_CRT_BASE_ADDR, sizeof(vid_port));
if(vid_port == C_6845) {
vid_mem_base = COLOR_BASE;
vid_mem_size = COLOR_SIZE;
} else {
vid_mem_base = MONO_BASE;
vid_mem_size = MONO_SIZE;
}
if(get_video() >= 3)
vid_mem_size = EGA_SIZE;
#else /* DOS */
/* Take the monitor out of the memory map if we have memory to spare,
* note that only half our PSP is needed at the new place, the first
@@ -859,6 +880,9 @@ void get_parameters(void)
b_setvar(E_SPECIAL|E_VAR|E_DEV, "rootdev", "ram");
b_setvar(E_SPECIAL|E_VAR|E_DEV, "ramimagedev", "bootdev");
b_setvar(E_SPECIAL|E_VAR, "ramsize", "0");
#define STRINGIT2(x) #x
#define STRINGIT1(x) STRINGIT2(x)
b_setvar(E_SPECIAL|E_VAR, "hz", STRINGIT1(DEFAULT_HZ));
#if BIOS
processor = getprocessor();
if(processor == 1586) processor = 686;
@@ -1066,9 +1090,6 @@ dev_t name2dev(char *name)
if (strcmp(n, "ram") == 0) {
dev= DEV_RAM;
} else
if (strcmp(n, "boot") == 0) {
dev= DEV_BOOT;
} else
if (n[0] == 'f' && n[1] == 'd' && numeric(n+2)) {
/* Floppy. */
tmpdev.device= a2l(n+2);
@@ -1369,11 +1390,15 @@ void boot_device(char *devname)
void ctty(char *line)
{
if (between('0', line[0], '3') && line[1] == 0) {
serial_init(line[0] - '0');
if (line == nil) {
serial_line = -1;
} else if (between('0', line[0], '3') && line[1] == 0) {
serial_line = line[0] - '0';
} else {
printf("Bad serial line number: %s\n", line);
return;
}
serial_init(serial_line);
}
#else /* DOS */
@@ -1793,6 +1818,7 @@ void execute(void)
case R_HELP: help(); ok= 1; break;
case R_EXIT: exit(0);
case R_OFF: off(); ok= 1; break;
case R_CTTY: ctty(nil); ok= 1; break;
}
/* Command to check bootparams: */
@@ -1850,9 +1876,6 @@ void monitor(void)
#if BIOS
unsigned char cdspec[25];
void bootcdinfo(u32_t, int *, int drive);
void boot(void)
/* Load Minix and start it, among other things. */
{
@@ -1955,3 +1978,4 @@ void main(int argc, char **argv)
/*
* $PchId: boot.c,v 1.14 2002/02/27 19:46:14 philip Exp $
*/

View File

@@ -640,7 +640,7 @@ _getch:
test ax, ax
jnz gotch
getch:
hlt ! Play dead until interrupted (see pause())
! hlt ! Play dead until interrupted (see pause())
movb ah, #0x01 ! Keyboard status
int 0x16
jz 0f ! Nothing typed
@@ -741,7 +741,7 @@ nulch: ret
! power, or tells an x86 emulator that nothing is happening right now.
.define _pause
_pause:
hlt
! hlt
ret
! void set_mode(unsigned mode);
@@ -854,6 +854,9 @@ restore_video: ! To restore the video mode on exit
_serial_init:
mov bx, sp
mov dx, 2(bx) ! Line number
mov line, #0
test dx, dx ! Off if line number < 0
js 0f
push ds
xor ax, ax
mov ds, ax ! Vector and BIOS data segment

View File

@@ -18,6 +18,8 @@
#include <minix/const.h>
#include <minix/type.h>
#include <minix/syslib.h>
#include <minix/tty.h>
#include <sys/video.h>
#include <kernel/const.h>
#include <kernel/type.h>
#include <ibm/partition.h>
@@ -27,6 +29,11 @@
static int block_size = 0;
extern int serial_line;
extern u16_t vid_port; /* Video i/o port. */
extern u32_t vid_mem_base; /* Video memory base address. */
extern u32_t vid_mem_size; /* Video memory size. */
#define click_shift clck_shft /* 7 char clash with click_size. */
/* Some kernels have extra features: */
@@ -45,7 +52,7 @@ static int block_size = 0;
/* Data about the different processes. */
#define PROCESS_MAX 16 /* Must match the space in kernel/mpx.x */
#define KERNEL 0 /* The first process is the kernel. */
#define KERNEL_IDX 0 /* The first process is the kernel. */
#define FS 2 /* The third must be fs. */
struct process { /* Per-process memory adresses. */
@@ -194,7 +201,7 @@ void patch_sizes(void)
/* Patch text and data sizes of the processes into kernel data space.
*/
doff= process[KERNEL].data + P_SIZ_OFF;
doff= process[KERNEL_IDX].data + P_SIZ_OFF;
for (i= 0; i < n_procs; i++) {
procp= &process[i];
@@ -376,6 +383,42 @@ int get_segment(u32_t *vsec, long *size, u32_t *addr, u32_t limit)
return 1;
}
static void restore_screen(void)
{
struct boot_tty_info boot_tty_info;
u32_t info_location;
#define LINES 25
#define CHARS 80
static u16_t consolescreen[LINES][CHARS];
/* Try and find out what the main console was displaying
* by looking into video memory.
*/
info_location = vid_mem_base+vid_mem_size-sizeof(boot_tty_info);
raw_copy(mon2abs(&boot_tty_info), info_location,
sizeof(boot_tty_info));
if(boot_tty_info.magic == TTYMAGIC) {
if(boot_tty_info.flags & (BTIF_CONSORIGIN|BTIF_CONSCURSOR) ==
(BTIF_CONSORIGIN|BTIF_CONSCURSOR)) {
int line;
raw_copy(mon2abs(consolescreen),
vid_mem_base + boot_tty_info.consorigin,
sizeof(consolescreen));
clear_screen();
for(line = 0; line < LINES; line++) {
int ch;
for(ch = 0; ch < CHARS; ch++) {
u16_t newch = consolescreen[line][ch] & BYTE;
if(newch < ' ') newch = ' ';
putch(newch);
}
}
}
}
}
void exec_image(char *image)
/* Get a Minix image into core, patch it up and execute. */
{
@@ -445,7 +488,7 @@ void exec_image(char *image)
}
/* Get the click shift from the kernel text segment. */
if (i == KERNEL) {
if (i == KERNEL_IDX) {
if (!get_clickshift(vsec, &hdr)) return;
addr= align(addr, click_size);
}
@@ -504,7 +547,7 @@ void exec_image(char *image)
if (!get_segment(&vsec, &a_data, &addr, limit)) return;
/* Make space for bss and stack unless... */
if (i != KERNEL && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
if (i != KERNEL_IDX && (k_flags & K_CLAIM)) a_bss= a_stack= 0;
printf("%07lx %07lx %8ld %8ld %8ld",
procp->cs, procp->ds,
@@ -554,7 +597,7 @@ void exec_image(char *image)
}
/* Check the kernel magic number. */
if (get_word(process[KERNEL].data + MAGIC_OFF) != KERNEL_D_MAGIC) {
if (get_word(process[KERNEL_IDX].data + MAGIC_OFF) != KERNEL_D_MAGIC) {
printf("Kernel magic number is incorrect\n");
errno= 0;
return;
@@ -592,8 +635,8 @@ void exec_image(char *image)
(void) dev_close();
/* Minix. */
minix(process[KERNEL].entry, process[KERNEL].cs,
process[KERNEL].ds, params, sizeof(params), aout);
minix(process[KERNEL_IDX].entry, process[KERNEL_IDX].cs,
process[KERNEL_IDX].ds, params, sizeof(params), aout);
if (!(k_flags & K_BRET)) {
extern u32_t reboot_code;
@@ -607,8 +650,13 @@ void exec_image(char *image)
/* Read leftover character, if any. */
scan_keyboard();
/* Restore screen contents. */
restore_screen();
}
ino_t latest_version(char *version, struct stat *stp)
/* Recursively read the current directory, selecting the newest image on
* the way up. (One can't use r_stat while reading a directory.)
@@ -701,6 +749,13 @@ void bootminix(void)
if ((image= select_image(b_value("image"))) == nil) return;
if(serial_line >= 0) {
char linename[2];
linename[0] = serial_line + '0';
linename[1] = '\0';
b_setvar(E_VAR, SERVARNAME, linename);
}
exec_image(image);
switch (errno) {
@@ -716,6 +771,9 @@ void bootminix(void)
/* No error or error already reported. */;
}
free(image);
if(serial_line >= 0)
b_unset(SERVARNAME);
}
/*

View File

@@ -14,11 +14,11 @@
#include <minix/config.h>
#include <minix/const.h>
#include <minix/type.h>
#include <servers/fs/const.h>
#include <servers/fs/type.h>
#include <servers/fs/buf.h>
#include <servers/fs/super.h>
#include <servers/fs/inode.h>
#include <servers/mfs/const.h>
#include <servers/mfs/type.h>
#include <servers/mfs/buf.h>
#include <servers/mfs/super.h>
#include <servers/mfs/inode.h>
#include "rawfs.h"
void readblock(off_t blockno, char *buf, int);
@@ -61,7 +61,7 @@ static char dirbuf[_MAX_BLOCK_SIZE]; /* Scratch/Directory block. */
static block_t a_indir, a_dindir; /* Addresses of the indirects. */
static off_t dirpos; /* Reading pos in a dir. */
#define fsbuf(b) (* (struct buf *) (b))
#define fsbuf(b) (* (union fsdata_u *) (b))
#define zone_shift (super.s_log_zone_size) /* zone to block ratio */
@@ -110,6 +110,7 @@ void r_stat(Ino_t inum, struct stat *stp)
block_t block;
block_t ino_block;
ino_t ino_offset;
union fsdata_u *blockbuf;
/* Calculate start of i-list */
block = START_BLOCK + super.s_imap_blocks + super.s_zmap_blocks;
@@ -120,13 +121,14 @@ void r_stat(Ino_t inum, struct stat *stp)
block += ino_block;
/* Fetch the block */
readblock(block, scratch, block_size);
blockbuf = (union fsdata_u *) scratch;
readblock(block, blockbuf, block_size);
if (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3) {
d2_inode *dip;
int i;
dip= &fsbuf(scratch).b_v2_ino[ino_offset];
dip= &blockbuf->b__v2_ino[ino_offset];
curfil.i_mode= dip->d2_mode;
curfil.i_nlinks= dip->d2_nlinks;
@@ -142,7 +144,7 @@ void r_stat(Ino_t inum, struct stat *stp)
d1_inode *dip;
int i;
dip= &fsbuf(scratch).b_v1_ino[ino_offset];
dip= &blockbuf->b__v1_ino[ino_offset];
curfil.i_mode= dip->d1_mode;
curfil.i_nlinks= dip->d1_nlinks;
@@ -263,8 +265,8 @@ off_t r_vir2abs(off_t virblk)
i = zone / (zone_t) nr_indirects;
ind_zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
? fsbuf(dindir).b_v2_ind[i]
: fsbuf(dindir).b_v1_ind[i];
? fsbuf(dindir).b__v2_ind[i]
: fsbuf(dindir).b__v1_ind[i];
zone %= (zone_t) nr_indirects;
}
if (ind_zone == 0) return 0;
@@ -276,8 +278,8 @@ off_t r_vir2abs(off_t virblk)
a_indir= z;
}
zone = (super.s_magic == SUPER_V2 || super.s_magic == SUPER_V3)
? fsbuf(indir).b_v2_ind[(int) zone]
: fsbuf(indir).b_v1_ind[(int) zone];
? fsbuf(indir).b__v2_ind[(int) zone]
: fsbuf(indir).b__v1_ind[(int) zone];
/* Calculate absolute datablock number */
z = ((block_t) zone << zone_shift) + zone_index;

27
boot/updateboot.sh Executable file
View File

@@ -0,0 +1,27 @@
#!/bin/sh
set -e
BOOT=/boot/boot
ROOT=`printroot -r`
if [ ! -b "$ROOT" ]
then echo root device $ROOT not found
exit 1
fi
echo -n "Install boot as $BOOT on current root and patch into $ROOT? (y/N) "
read ans
if [ ! "$ans" = y ]
then echo Aborting.
exit 1
fi
make install || true
echo Installing boot monitor into $BOOT.
cp boot $BOOT
echo Patching position of $BOOT into $ROOT.
installboot -d "$ROOT" /usr/mdec/bootblock $BOOT
sync

View File

@@ -2,8 +2,9 @@
MAKE = exec make -$(MAKEFLAGS)
BZIP2=bzip2-1.0.3
FLEX=flex-2.5.4
SMALLPROGRAMS=`arch` aal advent ash autil awk bc byacc cawf cron de dhcpd dis88 elle elvis ftp ftpd200 httpd ibm indent m4 make mdb mined patch pax ps reboot rlogind scripts sh simple syslogd talk talkd telnet telnetd urlget yap zmodem
SMALLPROGRAMS=`arch` aal advent ash autil awk byacc cawf cron de dhcpd dis88 elle elvis ftp101 ftpd200 ibm indent m4 make mined patch pax profile ps reboot rlogind scripts sh simple syslogd talk talkd telnet telnetd urlget yap zoneinfo
usage:
@echo "Usage: make all # Compile all commands" >&2
@@ -16,20 +17,28 @@ usage:
@echo " "
@echo "big compiles the commands the require large compiler sizes."
@echo "small compiles the rest. all compiles all."
@false
all: small big
all: big small
install: biginstall smallinstall
install: big biginstall small smallinstall
big:
binsizes big
cd zmodem && make
cd $(BZIP2) && /bin/sh build build
binsizes normal
biginstall: big
binsizes big
cd zmodem && make install
cd $(BZIP2) && make install
cd $(FLEX) && sh build
binsizes normal
clean::
cd $(BZIP2) && make clean
cd zmodem && make clean
if [ -f $(FLEX)/Makefile ]; then cd $(FLEX) && make distclean ; fi
for p in $(SMALLPROGRAMS); do ( cd $$p && make clean ); done
small::

View File

@@ -1,50 +1,70 @@
# Makefile for ash.
SRCS= builtins.c cd.c dirent.c error.c eval.c exec.c expand.c input.c \
SRCS= alias.c builtins.c cd.c error.c eval.c exec.c expand.c histedit.c \
input.c \
jobs.c mail.c main.c memalloc.c miscbltin.c mystring.c nodes.c \
options.c parser.c redir.c show.c signames.c syntax.c trap.c \
options.c parser.c redir.c setmode.c show.c signames.c syntax.c \
trap.c \
output.c var.c
OBJS= builtins.o cd.o dirent.o error.o eval.o exec.o expand.o input.o \
OBJS= alias.o builtins.o cd.o error.o eval.o exec.o expand.o histedit.o \
input.o \
jobs.o mail.o main.o memalloc.o miscbltin.o mystring.o nodes.o \
options.o parser.o redir.o show.o signames.o syntax.o trap.o \
options.o parser.o redir.o setmode.o show.o signames.o syntax.o \
trap.o \
output.o var.o init.o \
bltin/echo.o bltin/expr.o bltin/operators.o bltin/regexp.o
bltin/echo.o bltin/expr.o bltin/operators.o bltin/regexp.o \
arith.o arith_lex.o
#
# Set READLINE in shell.h and add -ledit to LIBS if you want to use the
# editline package by Simmule Turner and Rich Salz. (The big, bloated
# and GPL contaminated FSF readline should work too.)
#
CPPFLAGS= -DSHELL -I. -D_MINIX -D_POSIX_SOURCE
CFLAGS= -wo -i $(CPPFLAGS)
LIBS= -ledit
CC = exec cc
LEX=flex
YACC=/usr/bin/yacc
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
# Enable this line to disable command line editing
#EDIT=-DNO_HISTORY
# Enable this line to use the editline library instead of libedit
EDIT=-DEDITLINE
EDITLIB=-ledit
FLEXLIB=-lfl
# Enable this line if your system does not have a <paths.h>
NO_PATHS_H=-DNO_PATHS_H
# Enable this if you don't want job control
NO_JOBS=-DJOBS=0
MKB_NO_JOBS=-j
CPPFLAGS= -DSHELL -I. -D_MINIX $(EDIT) $(NO_PATHS_H) $(NO_JOBS)
CFLAGS= $(OPT) $(CPPFLAGS)
LIBS= $(EDITLIB) $(FLEXLIB)
CLEANFILES= $(OBJS) \
builtins.c builtins.h init.c mkinit mknodes mksignames mksyntax \
nodes.c nodes.h signames.c signames.h syntax.c syntax.h token.def \
arith.c arith_y.h arith_lex.c builtins.c builtins.h init.c \
mkinit mknodes mksignames mksyntax \
nodes.c nodes.h signames.c signames.h syntax.c syntax.h token.h \
bltin/operators.h bltin/operators.c
all: sh
sh: $(OBJS)
$(CC) $(CFLAGS) -o sh $(OBJS) $(LIBS)
install -S 100k sh
$(CC) $(CFLAGS) -fnone -o sh $(OBJS) $(LIBS)
install -S 136k sh
install: /usr/bin/ash /usr/bin/sh /bin/sh /bin/bigsh
/usr/bin/ash: sh
install -cs -o bin $? $@
install -cs -o bin $< $@
/usr/bin/sh: /usr/bin/ash
install -l $? $@
install -l $< $@
/bin/sh: /usr/bin/ash
install -lcs $? $@
install -lcs $< $@
/bin/bigsh: /usr/bin/ash
install -S 1500000 -lcs $? $@
install -S 6600k -lcs $< $@
clean:
rm -f $(CLEANFILES) sh core
@@ -54,11 +74,18 @@ parser.o: token.def
token.def: mktokens
sh mktokens
builtins.c builtins.h: builtins.table shell.h
sh mkbuiltins shell.h builtins.table
arith.c: arith.y
$(YACC) -d $<
mv y.tab.c $@
mv y.tab.h arith_y.h
init.o: mkinit $(SRCS)
./mkinit '$(CC) -c $(CFLAGS) init.c' $(SRCS)
arith_lex.c: arith_lex.l
builtins.c builtins.h: builtins.def shell.h
sh mkbuiltins $(MKB_NO_JOBS) . shell.h builtins.def
init.c: mkinit $(SRCS)
./mkinit $(SRCS)
mkinit: mkinit.c
$(CC) $(CFLAGS) mkinit.c -o $@
@@ -81,20 +108,8 @@ syntax.c syntax.h: mksyntax
mksyntax: mksyntax.c parser.h
$(CC) $(CFLAGS) mksyntax.c -o $@
bltin/operators.h: bltin/mkexpr bltin/binary_op bltin/unary_op
cd bltin && sh mkexpr
bltin/echo.o: bltin/echo.c
cd bltin && $(CC) -I.. $(CFLAGS) -c echo.c
bltin/expr.o: bltin/expr.c
cd bltin && $(CC) -I.. $(CFLAGS) -c expr.c
bltin/operators.o: bltin/operators.c
cd bltin && $(CC) -I.. $(CFLAGS) -c operators.c
bltin/regexp.o: bltin/regexp.c
cd bltin && $(CC) -I.. $(CFLAGS) -c regexp.c
bltin/operators.h: bltin/mkexpr bltin/unary_op bltin/binary_op
cd bltin && sh mkexpr unary_op binary_op
# Dependencies you say? This will have to do.
$(OBJS): error.h eval.h exec.h expand.h init.h input.h \
@@ -103,3 +118,6 @@ $(OBJS): error.h eval.h exec.h expand.h init.h input.h \
builtins.h nodes.h signames.h syntax.h
bltin/expr.o bltin/operators.o: bltin/operators.h
#
# $PchId: Makefile,v 1.4 2006/05/22 12:40:46 philip Exp $

View File

@@ -1,4 +1,13 @@
# @(#)TOUR 5.1 (Berkeley) 3/7/91
# @(#)TOUR 8.1 (Berkeley) 5/31/93
# $FreeBSD: src/bin/sh/TOUR,v 1.6 1999/08/27 23:15:07 peter Exp $
NOTE -- This is the original TOUR paper distributed with ash and
does not represent the current state of the shell. It is provided anyway
since it provides helpful information for how the shell is structured,
but be warned that things have changed -- the current shell is
still under development.
================================================================
A Tour through Ash
@@ -20,7 +29,7 @@ programs is:
mknodes nodetypes nodes.h nodes.c
mksignames - signames.h signames.c
mksyntax - syntax.h syntax.c
mktokens - token.def
mktokens - token.h
bltin/mkexpr unary_op binary_op operators.h operators.c
There are undoubtedly too many of these. Mkinit searches all the
@@ -346,3 +355,6 @@ cause the preprocessor can't handle functions with a variable
number of arguments. Defining DEBUG also causes the shell to
generate a core dump if it is sent a quit signal. The tracing
code is in show.c.
#
# $PchId: TOUR,v 1.3 2006/03/31 11:33:46 philip Exp $

265
commands/ash/alias.c Normal file
View File

@@ -0,0 +1,265 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/alias.c,v 1.18 2004/04/06 20:06:51 markm Exp $");
*/
#include <stdlib.h>
#include "shell.h"
#include "input.h"
#include "output.h"
#include "error.h"
#include "memalloc.h"
#include "mystring.h"
#include "alias.h"
#include "options.h" /* XXX for argptr (should remove?) */
#include "builtins.h"
#define ATABSIZE 39
STATIC struct alias *atab[ATABSIZE];
STATIC void setalias(char *, char *);
STATIC int unalias(char *);
STATIC struct alias **hashalias(char *);
STATIC
void
setalias(char *name, char *val)
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; ap = ap->next) {
if (equal(name, ap->name)) {
INTOFF;
ckfree(ap->val);
ap->val = savestr(val);
INTON;
return;
}
}
/* not found */
INTOFF;
ap = ckmalloc(sizeof (struct alias));
ap->name = savestr(name);
/*
* XXX - HACK: in order that the parser will not finish reading the
* alias value off the input before processing the next alias, we
* dummy up an extra space at the end of the alias. This is a crock
* and should be re-thought. The idea (if you feel inclined to help)
* is to avoid alias recursions. The mechanism used is: when
* expanding an alias, the value of the alias is pushed back on the
* input as a string and a pointer to the alias is stored with the
* string. The alias is marked as being in use. When the input
* routine finishes reading the string, it marks the alias not
* in use. The problem is synchronization with the parser. Since
* it reads ahead, the alias is marked not in use before the
* resulting token(s) is next checked for further alias sub. The
* H A C K is that we add a little fluff after the alias value
* so that the string will not be exhausted. This is a good
* idea ------- ***NOT***
*/
#ifdef notyet
ap->val = savestr(val);
#else /* hack */
{
int len = strlen(val);
ap->val = ckmalloc(len + 2);
memcpy(ap->val, val, len);
ap->val[len] = ' '; /* fluff */
ap->val[len+1] = '\0';
}
#endif
ap->flag = 0;
ap->next = *app;
*app = ap;
INTON;
}
STATIC int
unalias(char *name)
{
struct alias *ap, **app;
app = hashalias(name);
for (ap = *app; ap; app = &(ap->next), ap = ap->next) {
if (equal(name, ap->name)) {
/*
* if the alias is currently in use (i.e. its
* buffer is being used by the input routine) we
* just null out the name instead of freeing it.
* We could clear it out later, but this situation
* is so rare that it hardly seems worth it.
*/
if (ap->flag & ALIASINUSE)
*ap->name = '\0';
else {
INTOFF;
*app = ap->next;
ckfree(ap->name);
ckfree(ap->val);
ckfree(ap);
INTON;
}
return (0);
}
}
return (1);
}
#ifdef mkinit
INCLUDE "alias.h"
SHELLPROC {
rmaliases();
}
#endif
void
rmaliases(void)
{
struct alias *ap, *tmp;
int i;
INTOFF;
for (i = 0; i < ATABSIZE; i++) {
ap = atab[i];
atab[i] = NULL;
while (ap) {
ckfree(ap->name);
ckfree(ap->val);
tmp = ap;
ap = ap->next;
ckfree(tmp);
}
}
INTON;
}
struct alias *
lookupalias(char *name, int check)
{
struct alias *ap = *hashalias(name);
for (; ap; ap = ap->next) {
if (equal(name, ap->name)) {
if (check && (ap->flag & ALIASINUSE))
return (NULL);
return (ap);
}
}
return (NULL);
}
/*
* TODO - sort output
*/
int
aliascmd(int argc, char **argv)
{
char *n, *v;
int ret = 0;
struct alias *ap;
if (argc == 1) {
int i;
for (i = 0; i < ATABSIZE; i++)
for (ap = atab[i]; ap; ap = ap->next) {
if (*ap->name != '\0') {
out1fmt("alias %s=", ap->name);
out1qstr(ap->val);
out1c('\n');
}
}
return (0);
}
while ((n = *++argv) != NULL) {
if ((v = strchr(n+1, '=')) == NULL) /* n+1: funny ksh stuff */
if ((ap = lookupalias(n, 0)) == NULL) {
outfmt(out2, "alias: %s not found\n", n);
ret = 1;
} else {
out1fmt("alias %s=", n);
out1qstr(ap->val);
out1c('\n');
}
else {
*v++ = '\0';
setalias(n, v);
}
}
return (ret);
}
int
unaliascmd(int argc __unused, char **argv __unused)
{
int i;
while ((i = nextopt("a")) != '\0') {
if (i == 'a') {
rmaliases();
return (0);
}
}
for (i = 0; *argptr; argptr++)
i = unalias(*argptr);
return (i);
}
STATIC struct alias **
hashalias(char *p)
{
unsigned int hashval;
hashval = *p << 4;
while (*p)
hashval+= *p++;
return &atab[hashval % ATABSIZE];
}
/*
* $PchId: alias.c,v 1.5 2006/05/22 12:41:12 philip Exp $
*/

52
commands/ash/alias.h Normal file
View File

@@ -0,0 +1,52 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)alias.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/alias.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#define ALIASINUSE 1
struct alias {
struct alias *next;
char *name;
char *val;
int flag;
};
struct alias *lookupalias(char *, int);
int aliascmd(int, char **);
int unaliascmd(int, char **);
void rmaliases(void);
/*
* $PchId: alias.h,v 1.4 2006/03/31 11:30:54 philip Exp $
*/

39
commands/ash/arith.h Normal file
View File

@@ -0,0 +1,39 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)arith.h 1.1 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/arith.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
int arith(char *);
int arith_assign(char *, arith_t);
int expcmd(int, char **);
/*
* $PchId: arith.h,v 1.3 2006/03/31 11:25:25 philip Exp $
*/

366
commands/ash/arith.y Normal file
View File

@@ -0,0 +1,366 @@
%{
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/arith.y,v 1.19 2004/05/24 10:11:31 stefanf Exp $");
*/
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include "shell.h"
#include "arith.h"
#include "arith_lex.h"
#include "var.h"
%}
%union {
arith_t l_value;
char* s_value;
}
%token <l_value> ARITH_NUM ARITH_LPAREN ARITH_RPAREN
%token <s_value> ARITH_VAR
%type <l_value> expr
%right ARITH_ASSIGN
%right ARITH_ADDASSIGN ARITH_SUBASSIGN
%right ARITH_MULASSIGN ARITH_DIVASSIGN ARITH_REMASSIGN
%right ARITH_RSHASSIGN ARITH_LSHASSIGN
%right ARITH_BANDASSIGN ARITH_BXORASSIGN ARITH_BORASSIGN
%left ARITH_OR
%left ARITH_AND
%left ARITH_BOR
%left ARITH_BXOR
%left ARITH_BAND
%left ARITH_EQ ARITH_NE
%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE
%left ARITH_LSHIFT ARITH_RSHIFT
%left ARITH_ADD ARITH_SUB
%left ARITH_MUL ARITH_DIV ARITH_REM
%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT
%%
exp:
expr
{ return ($1); }
;
expr:
ARITH_LPAREN expr ARITH_RPAREN
{ $$ = $2; } |
expr ARITH_OR expr
{ $$ = $1 ? $1 : $3 ? $3 : 0; } |
expr ARITH_AND expr
{ $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } |
expr ARITH_BOR expr
{ $$ = $1 | $3; } |
expr ARITH_BXOR expr
{ $$ = $1 ^ $3; } |
expr ARITH_BAND expr
{ $$ = $1 & $3; } |
expr ARITH_EQ expr
{ $$ = $1 == $3; } |
expr ARITH_GT expr
{ $$ = $1 > $3; } |
expr ARITH_GE expr
{ $$ = $1 >= $3; } |
expr ARITH_LT expr
{ $$ = $1 < $3; } |
expr ARITH_LE expr
{ $$ = $1 <= $3; } |
expr ARITH_NE expr
{ $$ = $1 != $3; } |
expr ARITH_LSHIFT expr
{ $$ = $1 << $3; } |
expr ARITH_RSHIFT expr
{ $$ = $1 >> $3; } |
expr ARITH_ADD expr
{ $$ = $1 + $3; } |
expr ARITH_SUB expr
{ $$ = $1 - $3; } |
expr ARITH_MUL expr
{ $$ = $1 * $3; } |
expr ARITH_DIV expr
{
if ($3 == 0)
yyerror("division by zero");
$$ = $1 / $3;
} |
expr ARITH_REM expr
{
if ($3 == 0)
yyerror("division by zero");
$$ = $1 % $3;
} |
ARITH_NOT expr
{ $$ = !($2); } |
ARITH_BNOT expr
{ $$ = ~($2); } |
ARITH_SUB expr %prec ARITH_UNARYMINUS
{ $$ = -($2); } |
ARITH_ADD expr %prec ARITH_UNARYPLUS
{ $$ = $2; } |
ARITH_NUM |
ARITH_VAR
{
char *p;
arith_t arith_val;
char *str_val;
if (lookupvar($1) == NULL)
setvarsafe($1, "0", 0);
str_val = lookupvar($1);
arith_val = strtoarith_t(str_val, &p, 0);
/*
* Conversion is successful only in case
* we've converted _all_ characters.
*/
if (*p != '\0')
yyerror("variable conversion error");
$$ = arith_val;
} |
ARITH_VAR ARITH_ASSIGN expr
{
if (arith_assign($1, $3) != 0)
yyerror("variable assignment error");
$$ = $3;
} |
ARITH_VAR ARITH_ADDASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) + $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_SUBASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) - $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_MULASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) * $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_DIVASSIGN expr
{
arith_t value;
if ($3 == 0)
yyerror("division by zero");
value = atoarith_t(lookupvar($1)) / $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_REMASSIGN expr
{
arith_t value;
if ($3 == 0)
yyerror("division by zero");
value = atoarith_t(lookupvar($1)) % $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_RSHASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) >> $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_LSHASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) << $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BANDASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) & $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BXORASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) ^ $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} |
ARITH_VAR ARITH_BORASSIGN expr
{
arith_t value;
value = atoarith_t(lookupvar($1)) | $3;
if (arith_assign($1, value) != 0)
yyerror("variable assignment error");
$$ = value;
} ;
%%
#include "error.h"
#include "output.h"
#include "memalloc.h"
#include "builtins.h"
#define lstrlen(var) (3 + (2 + CHAR_BIT * sizeof((var))) / 3)
char *arith_buf, *arith_startbuf;
int yylex(void);
int yyparse(void);
int
arith_assign(char *name, arith_t value)
{
char *str;
int ret;
str = (char *)ckmalloc(lstrlen(value));
sprintf(str, ARITH_FORMAT_STR, value);
ret = setvarsafe(name, str, 0);
free(str);
return ret;
}
int
arith(char *s)
{
long result;
arith_buf = arith_startbuf = s;
INTOFF;
result = yyparse();
arith_lex_reset(); /* Reprime lex. */
INTON;
return result;
}
void
yyerror(char *s)
{
yyerrok;
yyclearin;
arith_lex_reset(); /* Reprime lex. */
error("arithmetic expression: %s: \"%s\"", s, arith_startbuf);
}
/*
* The exp(1) builtin.
*/
int
expcmd(int argc, char **argv)
{
char *p;
char *concat;
char **ap;
long i;
if (argc > 1) {
p = argv[1];
if (argc > 2) {
/*
* Concatenate arguments.
*/
STARTSTACKSTR(concat);
ap = argv + 2;
for (;;) {
while (*p)
STPUTC(*p++, concat);
if ((p = *ap++) == NULL)
break;
STPUTC(' ', concat);
}
STPUTC('\0', concat);
p = grabstackstr(concat);
}
} else
p = "";
i = arith(p);
out1fmt("%ld\n", i);
return !i;
}
/*************************/
#ifdef TEST_ARITH
#include <stdio.h>
main(int argc, char *argv[])
{
printf("%d\n", exp(argv[1]));
}
error(char *s)
{
fprintf(stderr, "exp: %s\n", s);
exit(1);
}
#endif
/*
* $PchId: arith.y,v 1.6 2006/05/22 12:41:47 philip Exp $
*/

12
commands/ash/arith_lex.h Normal file
View File

@@ -0,0 +1,12 @@
/*
arith_lex.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
int yylex(void);
void arith_lex_reset(void);
/*
* $PchId: arith_lex.h,v 1.1 2001/05/18 19:57:55 philip Exp $
*/

138
commands/ash/arith_lex.l Normal file
View File

@@ -0,0 +1,138 @@
%{
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/arith_lex.l,v 1.22 2004/04/06 20:06:51 markm Exp $");
*/
#include <string.h>
#include "shell.h"
#include "arith_lex.h"
#include "arith_y.h"
#include "error.h"
#include "memalloc.h"
#include "var.h"
extern char *arith_buf, *arith_startbuf;
#undef YY_INPUT
#define YY_INPUT(buf,result,max) \
result = (*buf = *arith_buf++) ? 1 : YY_NULL;
#define YY_NO_UNPUT
%}
%%
[ \t\n] { ; }
0x[a-fA-F0-9]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 16);
return ARITH_NUM;
}
0[0-7]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 8);
return ARITH_NUM;
}
[0-9]+ {
yylval.l_value = strtoarith_t(yytext, NULL, 10);
return ARITH_NUM;
}
[A-Za-z][A-Za-z0-9_]* {
/*
* If variable doesn't exist, we should initialize
* it to zero.
*/
char *temp;
if (lookupvar(yytext) == NULL)
setvarsafe(yytext, "0", 0);
temp = (char *)ckmalloc(strlen(yytext) + 1);
yylval.s_value = strcpy(temp, yytext);
return ARITH_VAR;
}
"(" { return ARITH_LPAREN; }
")" { return ARITH_RPAREN; }
"||" { return ARITH_OR; }
"&&" { return ARITH_AND; }
"|" { return ARITH_BOR; }
"^" { return ARITH_BXOR; }
"&" { return ARITH_BAND; }
"==" { return ARITH_EQ; }
"!=" { return ARITH_NE; }
">" { return ARITH_GT; }
">=" { return ARITH_GE; }
"<" { return ARITH_LT; }
"<=" { return ARITH_LE; }
"<<" { return ARITH_LSHIFT; }
">>" { return ARITH_RSHIFT; }
"*" { return ARITH_MUL; }
"/" { return ARITH_DIV; }
"%" { return ARITH_REM; }
"+" { return ARITH_ADD; }
"-" { return ARITH_SUB; }
"~" { return ARITH_BNOT; }
"!" { return ARITH_NOT; }
"=" { return ARITH_ASSIGN; }
"+=" { return ARITH_ADDASSIGN; }
"-=" { return ARITH_SUBASSIGN; }
"*=" { return ARITH_MULASSIGN; }
"/=" { return ARITH_DIVASSIGN; }
"%=" { return ARITH_REMASSIGN; }
">>=" { return ARITH_RSHASSIGN; }
"<<=" { return ARITH_LSHASSIGN; }
"&=" { return ARITH_BANDASSIGN; }
"^=" { return ARITH_BXORASSIGN; }
"|=" { return ARITH_BORASSIGN; }
. {
error("arith: syntax error: \"%s\"\n", arith_startbuf);
}
%%
void
arith_lex_reset(void)
{
YY_NEW_FILE;
}
/*
* $PchId: arith_lex.l,v 1.5 2006/04/10 14:35:29 philip Exp $
*/

View File

@@ -1,26 +1,78 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)bltin.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/bltin/bltin.h,v 1.13 2004/04/06 20:06:53 markm Exp $
*/
/*
* This file is included by programs which are optionally built into the
* shell. If SHELL is defined, we try to map the standard UNIX library
* routines to ash routines using defines.
*
* Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
* This file is part of ash, which is distributed under the terms specified
* by the Ash General Public License. See the file named LICENSE.
*/
#include "../shell.h"
#include "../mystring.h"
#ifdef SHELL
#include "builtins.h"
#include "../output.h"
#undef stdout
#define stdout out1
#undef stderr
#define stderr out2
#define printf out1fmt
#undef putc
#define putc(c, file) outc(c, file)
#undef putchar
#define putchar(c) out1c(c)
#define fprintf outfmt
#define fputs outstr
#define fflush flushout
#define INITARGS(argv)
#define warnx1(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a); \
error("%s", buf); \
}
#define warnx2(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a, b); \
error("%s", buf); \
}
#define warnx3(a, b, c) { \
char buf[64]; \
(void)snprintf(buf, sizeof(buf), a, b, c); \
error("%s", buf); \
}
#else
#undef NULL
#include <stdio.h>
@@ -28,13 +80,12 @@
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else
#endif
#ifdef __STDC__
pointer stalloc(int);
void error(char *, ...);
#else
pointer stalloc();
void error();
#endif
void error(const char *, ...);
extern char *commandname;
/*
* $PchId: bltin.h,v 1.4 2006/03/29 11:39:00 philip Exp $
*/

View File

@@ -1,74 +1,126 @@
/*
* Echo command.
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
* This file is part of ash, which is distributed under the terms specified
* by the Ash General Public License. See the file named LICENSE.
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)echo.c 8.2 (Berkeley) 5/4/95
*/
#define main echocmd
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/bltin/echo.c,v 1.14 2004/04/06 20:06:53 markm Exp $");
*/
/*
* Echo command.
*/
#ifdef __minix
#define MINIX
#endif
#include "bltin.h"
#ifndef MINIX
/* #define eflag 1 */
#else
#undef eflag
main(argc, argv) char **argv; {
register char **ap;
register char *p;
register char c;
int count;
int nflag = 0;
#ifndef eflag
int eflag = 0;
#endif
ap = argv;
if (argc)
ap++;
if ((p = *ap) != NULL) {
if (equal(p, "--")) {
ap++;
}
if (equal(p, "-n")) {
nflag++;
ap++;
} else if (equal(p, "-e")) {
int
echocmd(argc, argv)
int argc;
char **argv;
{
char **ap;
char *p;
char c;
int count;
int nflag = 0;
#ifndef eflag
eflag++;
int eflag = 0;
#endif
ap++;
}
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
if (c == '\\' && eflag) {
switch (*p++) {
case 'b': c = '\b'; break;
case 'c': return 0; /* exit */
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break; /* c = '\\' */
case '0':
c = 0;
count = 3;
while (--count >= 0 && (unsigned)(*p - '0') < 8)
c = (c << 3) + (*p++ - '0');
break;
default:
p--;
break;
ap = argv;
if (argc)
ap++;
if ((p = *ap) != NULL) {
#ifdef MINIX
if (equal(p, "--")) {
ap++;
}
#endif
if (equal(p, "-n")) {
nflag++;
ap++;
} else if (equal(p, "-e")) {
#ifndef eflag
eflag++;
#endif
ap++;
}
}
while ((p = *ap++) != NULL) {
while ((c = *p++) != '\0') {
if (c == '\\' && eflag) {
switch (*p++) {
case 'a': c = '\a'; break;
case 'b': c = '\b'; break;
case 'c': return 0; /* exit */
case 'e': c = '\033'; break;
case 'f': c = '\f'; break;
case 'n': c = '\n'; break;
case 'r': c = '\r'; break;
case 't': c = '\t'; break;
case 'v': c = '\v'; break;
case '\\': break; /* c = '\\' */
case '0':
c = 0;
count = 3;
while (--count >= 0 && (unsigned)(*p - '0') < 8)
c = (c << 3) + (*p++ - '0');
break;
default:
p--;
break;
}
}
}
putchar(c);
}
if (*ap)
putchar(' ');
}
if (! nflag)
putchar('\n');
return 0;
putchar(c);
}
if (*ap)
putchar(' ');
}
if (! nflag)
putchar('\n');
return 0;
}
/*
* $PchId: echo.c,v 1.5 2006/05/23 12:05:56 philip Exp $
*/

View File

@@ -7,17 +7,14 @@
*/
#define main exprcmd
#include "bltin.h"
#include "operators.h"
#include <regex.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <unistd.h>
#ifndef S_ISLNK
#define lstat stat
#define S_ISLNK(mode) (0)
#endif
#define STACKSIZE 12
#define NESTINCR 16
@@ -50,7 +47,6 @@ struct operator {
struct filestat {
int op; /* OP_FILE or OP_LFILE */
char *name; /* name of file */
int rcode; /* return code from stat */
struct stat stat; /* status info on file */
@@ -63,24 +59,18 @@ extern short number_parens; /* number of \( \) pairs */
#ifdef __STDC__
int expr_is_false(struct value *);
void expr_operator(int, struct value *, struct filestat *);
int lookup_op(char *, char *const*);
char *re_compile(char *); /* defined in regexp.c */
int re_match(char *, char *); /* defined in regexp.c */
long atol(const char *);
static int expr_is_false(struct value *);
static void expr_operator(int, struct value *, struct filestat *);
static int lookup_op(char *, char *const*);
#else
int expr_is_false();
void expr_operator();
int lookup_op();
char *re_compile(); /* defined in regexp.c */
int re_match(); /* defined in regexp.c */
long atol();
static int expr_is_false();
static void expr_operator();
static int lookup_op();
#endif
main(argc, argv) char **argv; {
exprcmd(argc, argv) char **argv; {
char **ap;
char *opname;
char c;
@@ -146,6 +136,13 @@ overflow: error("Expression too complex");
continue;
} else {
if (opname[0] == '\'') {
for (p = opname ; *++p != '\0' ; );
if (--p > opname && *p == '\'') {
*p = '\0';
opname++;
}
}
valsp->type = STRING;
valsp->u.string = opname;
valsp++;
@@ -193,19 +190,11 @@ overflow: error("Expression too complex");
valsp->u.string = "";
}
valsp->type = STRING;
if (c >= OP_FILE
&& (fs.op != c
|| fs.name == NULL
if (c == OP_FILE
&& (fs.name == NULL
|| ! equal(fs.name, valsp->u.string))) {
fs.op = c;
fs.name = valsp->u.string;
if (c == OP_FILE) {
fs.rcode = stat(valsp->u.string,
&fs.stat);
} else {
fs.rcode = lstat(valsp->u.string,
&fs.stat);
}
fs.rcode = stat(valsp->u.string, &fs.stat);
}
}
if (binary < FIRST_BINARY_OP)
@@ -250,7 +239,7 @@ done:
}
int
static int
expr_is_false(val)
struct value *val;
{
@@ -274,14 +263,16 @@ expr_is_false(val)
* to stat, to avoid repeated stat calls on the same file.
*/
void
static void
expr_operator(op, sp, fs)
int op;
struct value *sp;
struct filestat *fs;
{
int i;
int i, r;
struct stat st1, st2;
regex_t pat;
regmatch_t rm[2];
switch (op) {
case NOT:
@@ -343,16 +334,16 @@ filebit:
if (fs->stat.st_mode & i && fs->rcode >= 0)
goto true;
goto false;
case ISSLINK:
if (lstat(fs->name, &st1) == -1)
goto false;
if (S_ISLNK(st1.st_mode))
goto true;
goto false;
case ISSIZE:
sp->u.num = fs->rcode >= 0? fs->stat.st_size : 0L;
sp->type = INTEGER;
break;
case ISLINK1:
case ISLINK2:
if (S_ISLNK(fs->stat.st_mode) && fs->rcode >= 0)
goto true;
fs->op = OP_FILE; /* not a symlink, so expect a -d or so next */
goto false;
case NEWER:
if (stat(sp->u.string, &st1) != 0) {
sp->u.num = 0;
@@ -439,19 +430,21 @@ filebit:
break;
case MATCHPAT:
{
char *pat;
pat = re_compile((sp + 1)->u.string);
if (re_match(pat, sp->u.string)) {
if (number_parens > 0) {
sp->u.string = match_begin[1];
sp->u.string[match_length[1]] = '\0';
r = regcomp(&pat, (sp + 1)->u.string, 0);
if (r)
error("Bad regular expression");
if (regexec(&pat, sp->u.string, 2, rm, 0) == 0 &&
rm[0].rm_so == 0)
{
if (pat.re_nsub > 0) {
sp->u.string[rm[1].rm_eo] = '\0';
sp->u.string = sp->u.string+rm[1].rm_so;
} else {
sp->u.num = match_length[0];
sp->u.num = rm[0].rm_eo;
sp->type = INTEGER;
}
} else {
if (number_parens > 0) {
if (pat.re_nsub > 0) {
sp->u.string[0] = '\0';
} else {
sp->u.num = 0;
@@ -464,7 +457,7 @@ filebit:
}
int
static int
lookup_op(name, table)
char *name;
char *const*table;

View File

@@ -5,21 +5,28 @@
# All calls to awk removed, because Minix bawk is deficient. (kjb)
if [ $# -ne 2 ]
then
echo "Usage: $0 <unary_op> <binary_op>" >&2
exit 1
fi
unary_op="$1"
binary_op="$2"
exec > operators.h
i=0
sed -e '/^[^#]/!d' unary_op binary_op | while read line
sed -e '/^[^#]/!d' "$unary_op" "$binary_op" | while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done
echo
echo "#define FIRST_BINARY_OP" `sed -e '/^[^#]/!d' unary_op | wc -l`
echo "#define FIRST_BINARY_OP" `sed -e '/^[^#]/!d' "$unary_op" | wc -l`
echo '
#define OP_INT 1 /* arguments to operator are integer */
#define OP_STRING 2 /* arguments to operator are string */
#define OP_FILE 3 /* argument is a file name */
#define OP_LFILE 4 /* argument is a file name of a symlink? */
extern char *const unary_op[];
extern char *const binary_op[];
@@ -31,14 +38,15 @@ echo '/*
* Operators used in the expr/test command.
*/
#include "../shell.h"
#include <stddef.h>
#include "shell.h"
#include "operators.h"
char *const unary_op[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* \([^ ][^ ]*\).*/ "\1",/
' unary_op
' "$unary_op"
echo ' NULL
};
@@ -46,7 +54,7 @@ char *const binary_op[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* \([^ ][^ ]*\).*/ "\1",/
' binary_op
' "$binary_op"
echo ' NULL
};
@@ -54,7 +62,7 @@ const char op_priority[] = {'
sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* [^ ][^ ]* \([^ ][^ ]*\).*/ \1,/
' unary_op binary_op
' "$unary_op" "$binary_op"
echo '};
const char op_argflag[] = {'
@@ -62,5 +70,5 @@ sed -e '/^[^#]/!d
s/[ ][ ]*/ /g
s/^[^ ][^ ]* [^ ][^ ]* [^ ][^ ]*$/& 0/
s/^[^ ][^ ]* [^ ][^ ]* [^ ][^ ]* \([^ ][^ ]*\)/ \1,/
' unary_op binary_op
' "$unary_op" "$binary_op"
echo '};'

View File

@@ -0,0 +1,8 @@
/*
myregexp.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
char *re_compile(char *pattern);
int re_match(char *pattern, char *string);

View File

@@ -8,7 +8,9 @@
*/
#include "bltin.h"
#include "myregexp.h"
#include <stdlib.h>
#define RE_END 0 /* end of regular expression */
#define RE_LITERAL 1 /* normal character follows */
@@ -27,7 +29,7 @@
char *match_begin[10];
short match_length[10];
short number_parens;
static int match();
static int match(char *pattern, char *string);
@@ -48,7 +50,6 @@ re_compile(pattern)
char stack[10];
int paren_num;
int i;
char *malloc();
p = pattern;
if (*p == '^')
@@ -176,6 +177,7 @@ out:
int
re_match(pattern, string)
char *pattern;
char *string;
@@ -246,7 +248,7 @@ ccl:
p++;
}
p++;
if (found == negate || c == 0)
if (found == negate)
goto bad;
break;
case RE_LP:

View File

@@ -16,9 +16,8 @@ ISFIFO -p 12 OP_FILE
ISSETUID -u 12 OP_FILE
ISSETGID -g 12 OP_FILE
ISSTICKY -k 12 OP_FILE
ISSLINK -h 12 OP_FILE
ISSIZE -s 12 OP_FILE
ISLINK1 -h 12 OP_LFILE
ISLINK2 -L 12 OP_LFILE
ISTTY -t 12 OP_INT
NULSTR -z 12 OP_STRING
STRLEN -n 12 OP_STRING

View File

@@ -1,3 +0,0 @@
#!/bin/sh
make clean
make && make install

21
commands/ash/builtins.table → commands/ash/builtins Executable file → Normal file
View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -34,19 +34,21 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)builtins 5.1 (Berkeley) 3/7/91
# @(#)builtins 8.1 (Berkeley) 5/31/93
#
# This file lists all the builtin commands. The first column is the name
# of a C routine. The -j flag, if present, specifies that this command
# is to be excluded from systems without job control. The rest of the line
# specifies the command name or names used to run the command. The entry
# for nullcmd, which is run when the user does not specify a command, must
# for bltincmd, which is run when the user does not specify a command, must
# come first.
#
# Copyright (C) 1989 by Kenneth Almquist. All rights reserved.
# This file is part of ash, which is distributed under the terms specified
# by the Ash General Public License. See the file named LICENSE.
#
# NOTE: bltincmd must come first!
bltincmd command
#alloccmd alloc
@@ -59,17 +61,19 @@ echocmd echo
evalcmd eval
execcmd exec
exitcmd exit
expcmd exp let
exportcmd export readonly
exprcmd expr test [
#exprcmd expr test [
histcmd fc
fgcmd -j fg
getoptscmd getopts
hashcmd hash
jobidcmd jobid
jobscmd jobs
#lccmd lc
#linecmd line
localcmd local
#nlechocmd nlecho
printfcmd printf
pwdcmd pwd
readcmd read
returncmd return
@@ -77,7 +81,10 @@ setcmd set
setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true false
truecmd : true
umaskcmd umask
unaliascmd unalias
unsetcmd unset
waitcmd wait
#foocmd foo
aliascmd alias

94
commands/ash/builtins.def Normal file
View File

@@ -0,0 +1,94 @@
#!/bin/sh -
#
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)builtins.def 8.4 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/builtins.def,v 1.14 2004/04/06 20:06:51 markm Exp $
#
# This file lists all the builtin commands. The first column is the name
# of a C routine. The -j flag, if present, specifies that this command
# is to be excluded from systems without job control, and the -h flag,
# if present specifies that this command is to be excluded from systems
# based on the NO_HISTORY compile-time symbol. The rest of the line
# specifies the command name or names used to run the command. The entry
# for bltincmd, which is run when the user does not specify a command, must
# come first.
#
# NOTE: bltincmd must come first!
bltincmd builtin
commandcmd command
#alloccmd alloc
bgcmd -j bg
breakcmd break continue
#catfcmd catf
cdcmd cd chdir
dotcmd .
echocmd echo
evalcmd eval
execcmd exec
exitcmd exit
expcmd exp let
exportcmd export readonly
exprcmd expr test [
falsecmd false
histcmd -h fc
fgcmd -j fg
getoptscmd getopts
hashcmd hash
jobidcmd jobid
jobscmd jobs
#linecmd line
localcmd local
#nlechocmd nlecho
#printfcmd printf
pwdcmd pwd
readcmd read
returncmd return
setcmd set
setvarcmd setvar
shiftcmd shift
trapcmd trap
truecmd : true
typecmd type
umaskcmd umask
unaliascmd unalias
unsetcmd unset
waitcmd wait
#foocmd foo
aliascmd alias
ulimitcmd ulimit
bindcmd bind
wordexpcmd wordexp
#
# $PchId: builtins.def,v 1.5 2006/03/31 10:50:57 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,22 @@
*/
#ifndef lint
static char sccsid[] = "@(#)cd.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/cd.c,v 1.34 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <limits.h>
/*
* The cd and pwd commands.
@@ -50,115 +60,124 @@ static char sccsid[] = "@(#)cd.c 5.2 (Berkeley) 3/13/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "exec.h"
#include "redir.h"
#include "mystring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include "builtins.h"
#include "show.h"
#include "cd.h"
#ifdef __STDC__
STATIC int cdlogical(char *);
STATIC int cdphysical(char *);
STATIC int docd(char *, int, int);
STATIC void updatepwd(char *);
STATIC void getpwd(void);
STATIC char *getcomponent(void);
#else
STATIC int docd();
STATIC void updatepwd();
STATIC void getpwd();
STATIC char *getcomponent();
#endif
STATIC int updatepwd(char *);
char *curdir; /* current working directory */
STATIC char *curdir = NULL; /* current working directory */
STATIC char *prevdir; /* previous working directory */
STATIC char *cdcomppath;
#if UDIR || TILDE
extern int didudir; /* set if /u/logname or ~logname expanded */
#endif
int
cdcmd(argc, argv) char **argv; {
cdcmd(int argc, char **argv)
{
char *dest;
char *path;
char *p;
struct stat statb;
char *padvance();
int tohome= 0;
int ch, phys, print = 0;
nextopt(nullstr);
if ((dest = *argptr) == NULL) {
if ((dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
tohome = 1;
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
phys = Pflag;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc > 1)
error("too many arguments");
if ((dest = *argv) == NULL && (dest = bltinlookup("HOME", 1)) == NULL)
error("HOME not set");
if (*dest == '\0')
dest = ".";
if (dest[0] == '-' && dest[1] == '\0') {
dest = prevdir ? prevdir : curdir;
if (dest)
print = 1;
else
dest = ".";
}
if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL)
path = nullstr;
while ((p = padvance(&path, dest)) != NULL) {
if (stat(p, &statb) >= 0
&& (statb.st_mode & S_IFMT) == S_IFDIR
&& docd(p, strcmp(p, dest), tohome) >= 0)
return 0;
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) {
if (!print) {
/*
* XXX - rethink
*/
if (p[0] == '.' && p[1] == '/' && p[2] != '\0')
p += 2;
print = strcmp(p, dest);
}
if (docd(p, print, phys) >= 0)
return 0;
}
}
error("can't cd to %s", dest);
/*NOTREACHED*/
return 0;
}
/*
* Actually do the chdir. If the name refers to symbolic links, we
* compute the actual directory name before doing the cd. In an
* interactive shell, print the directory name if "print" is nonzero
* or if the name refers to a symbolic link. We also print the name
* if "/u/logname" was expanded in it, since this is similar to a
* symbolic link. (The check for this breaks if the user gives the
* cd command some additional, unused arguments.)
* Actually change the directory. In an interactive shell, print the
* directory name if "print" is nonzero.
*/
#if SYMLINKS == 0
STATIC int
docd(dest, print, tohome)
char *dest;
{
#if UDIR || TILDE
if (didudir)
print = 1;
#endif
INTOFF;
if (chdir(dest) < 0) {
INTON;
return -1;
}
updatepwd(dest);
INTON;
if (print && iflag)
out1fmt("%s\n", stackblock());
docd(char *dest, int print, int phys)
{
TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, phys));
/* If logical cd fails, fall back to physical. */
if ((phys || cdlogical(dest) < 0) && cdphysical(dest) < 0)
return (-1);
if (print && iflag && curdir)
out1fmt("%s\n", curdir);
return 0;
}
#else
STATIC int
docd(dest, print, tohome)
char *dest;
{
register char *p;
register char *q;
char *symlink;
cdlogical(char *dest)
{
char *p;
char *q;
char *component;
struct stat statb;
int first;
int i;
int badstat;
TRACE(("docd(\"%s\", %d, %d) called\n", dest, print, tohome));
#if UDIR || TILDE
if (didudir)
print = 1;
#endif
top:
cdcomppath = dest;
/*
* Check each component of the path. If we find a symlink or
* something we can't stat, clear curdir to force a getcwd()
* next time we get the value of the current directory.
*/
badstat = 0;
cdcomppath = stalloc(strlen(dest) + 1);
scopy(dest, cdcomppath);
STARTSTACKSTR(p);
if (*dest == '/') {
STPUTC('/', p);
@@ -166,7 +185,7 @@ top:
}
first = 1;
while ((q = getcomponent()) != NULL) {
if (q[0] == '\0' || q[0] == '.' && q[1] == '\0')
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0'))
continue;
if (! first)
STPUTC('/', p);
@@ -177,71 +196,42 @@ top:
if (equal(component, ".."))
continue;
STACKSTRNUL(p);
if (lstat(stackblock(), &statb) < 0)
error("lstat %s failed", stackblock());
if ((statb.st_mode & S_IFMT) != S_IFLNK)
continue;
/* Hit a symbolic link. We have to start all over again. */
print = 1;
STPUTC('\0', p);
symlink = grabstackstr(p);
i = (int)statb.st_size + 2; /* 2 for '/' and '\0' */
if (cdcomppath != NULL)
i += strlen(cdcomppath);
p = stalloc(i);
if (readlink(symlink, p, (int)statb.st_size) < 0) {
error("readlink %s failed", stackblock());
if (lstat(stackblock(), &statb) < 0) {
badstat = 1;
break;
}
if (cdcomppath != NULL) {
p[(int)statb.st_size] = '/';
scopy(cdcomppath, p + (int)statb.st_size + 1);
} else {
p[(int)statb.st_size] = '\0';
}
if (p[0] != '/') { /* relative path name */
char *r;
q = r = symlink;
while (*q) {
if (*q++ == '/')
r = q;
}
*r = '\0';
dest = stalloc(strlen(symlink) + strlen(p) + 1);
scopy(symlink, dest);
strcat(dest, p);
} else {
dest = p;
}
goto top;
}
STPUTC('\0', p);
p = grabstackstr(p);
INTOFF;
/* The empty string is not a legal argument to chdir on a POSIX 1003.1
* system. */
if (p[0] != '\0' && chdir(p) < 0) {
if (updatepwd(badstat ? NULL : dest) < 0 || chdir(curdir) < 0) {
INTON;
return -1;
return (-1);
}
updatepwd(p);
INTON;
if (print && !tohome && iflag)
out1fmt("%s\n", p);
return 0;
return (0);
}
#endif /* SYMLINKS */
STATIC int
cdphysical(char *dest)
{
INTOFF;
if (chdir(dest) < 0 || updatepwd(NULL) < 0) {
INTON;
return (-1);
}
INTON;
return (0);
}
/*
* Get the next component of the path name pointed to by cdcomppath.
* This routine overwrites the string pointed to by cdcomppath.
*/
STATIC char *
getcomponent() {
register char *p;
getcomponent(void)
{
char *p;
char *start;
if ((p = cdcomppath) == NULL)
@@ -259,29 +249,43 @@ getcomponent() {
}
/*
* Update curdir (the name of the current directory) in response to a
* cd command. We also call hashcd to let the routines in exec.c know
* that the current directory has changed.
*/
void hashcd();
STATIC void
updatepwd(dir)
char *dir;
{
STATIC int
updatepwd(char *dir)
{
char *new;
char *p;
hashcd(); /* update command hash table */
/*
* If our argument is NULL, we don't know the current directory
* any more because we traversed a symbolic link or something
* we couldn't stat().
*/
if (dir == NULL || curdir == NULL) {
if (prevdir)
ckfree(prevdir);
INTOFF;
prevdir = curdir;
curdir = NULL;
if (getpwd() == NULL) {
INTON;
return (-1);
}
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
INTON;
return (0);
}
cdcomppath = stalloc(strlen(dir) + 1);
scopy(dir, cdcomppath);
STARTSTACKSTR(new);
if (*dir != '/') {
if (curdir == NULL)
return;
p = curdir;
while (*p)
STPUTC(*p++, new);
@@ -300,73 +304,87 @@ updatepwd(dir)
if (new == stackblock())
STPUTC('/', new);
STACKSTRNUL(new);
if (curdir)
ckfree(curdir);
INTOFF;
if (prevdir)
ckfree(prevdir);
prevdir = curdir;
curdir = savestr(stackblock());
setvar("PWD", curdir, VEXPORT);
setvar("OLDPWD", prevdir, VEXPORT);
INTON;
return (0);
}
int
pwdcmd(argc, argv) char **argv; {
getpwd();
out1str(curdir);
out1c('\n');
pwdcmd(int argc, char **argv)
{
char buf[PATH_MAX];
int ch, phys;
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
phys = Pflag;
while ((ch = getopt(argc, argv, "LP")) != -1) {
switch (ch) {
case 'L':
phys = 0;
break;
case 'P':
phys = 1;
break;
default:
error("unknown option: -%c", optopt);
break;
}
}
argc -= optind;
argv += optind;
if (argc != 0)
error("too many arguments");
if (!phys && getpwd()) {
out1str(curdir);
out1c('\n');
} else {
if (getcwd(buf, sizeof(buf)) == NULL)
error(".: %s", strerror(errno));
out1str(buf);
out1c('\n');
}
return 0;
}
/*
* Run /bin/pwd to find out what the current directory is. We suppress
* interrupts throughout most of this, but the user can still break out
* of it by killing the pwd program. If we already know the current
* Find out what the current directory is. If we already know the current
* directory, this routine returns immediately.
*/
#define MAXPWD 256
STATIC void
getpwd() {
char buf[MAXPWD];
char *p;
int i;
int status;
struct job *jp;
int pip[2];
char *
getpwd(void)
{
char buf[PATH_MAX];
if (curdir)
return;
INTOFF;
if (pipe(pip) < 0)
error("Pipe call failed");
jp = makejob((union node *)NULL, 1);
if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) {
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
close(pip[1]);
return curdir;
if (getcwd(buf, sizeof(buf)) == NULL) {
char *pwd = getenv("PWD");
struct stat stdot, stpwd;
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 &&
stat(pwd, &stpwd) != -1 &&
stdot.st_dev == stpwd.st_dev &&
stdot.st_ino == stpwd.st_ino) {
curdir = savestr(pwd);
return curdir;
}
execl("/bin/pwd", "pwd", (char *)0);
error("Cannot exec /bin/pwd");
return NULL;
}
close(pip[1]);
pip[1] = -1;
p = buf;
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0
|| i == -1 && errno == EINTR) {
if (i > 0)
p += i;
}
close(pip[0]);
pip[0] = -1;
status = waitforjob(jp);
if (status != 0)
error((char *)0);
if (i < 0 || p == buf || p[-1] != '\n')
error("pwd command failed");
p[-1] = '\0';
curdir = savestr(buf);
INTON;
return curdir;
}
/*
* $PchId: cd.c,v 1.6 2006/05/22 12:42:03 philip Exp $
*/

38
commands/ash/cd.h Normal file
View File

@@ -0,0 +1,38 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/bin/sh/cd.h,v 1.7 2004/04/06 20:06:51 markm Exp $
*/
char *getpwd(void);
int cdcmd (int, char **);
int pwdcmd(int, char **);
/*
* $PchId: cd.h,v 1.3 2006/03/31 09:59:04 philip Exp $
*/

354
commands/ash/complete.c Normal file
View File

@@ -0,0 +1,354 @@
/*
complete.c
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "myhistedit.h"
#include "shell.h"
#include "complete.h"
#include "error.h"
#include "expand.h"
#include "nodes.h"
#include "memalloc.h"
static char **getlist(EditLine *el, int *baselen, int *isdir);
static char **getlist_tilde(char *prefix);
static int vstrcmp(const void *v1, const void *v2);
static void print_list(char **list);
static int install_extra(EditLine *el, char **list, int baselen, int isdir);
unsigned char complete(EditLine *el, int ch)
{
struct stackmark mark;
const LineInfo *lf;
char **list;
int baselen, prefix, isdir;
/* Direct the cursor the the end of the word. */
for(;;)
{
lf = el_line(el);
if (lf->cursor < lf->lastchar &&
!isspace((unsigned char)*lf->cursor))
{
(*(char **)&lf->cursor)++; /* XXX */
}
else
break;
}
setstackmark(&mark);
list= getlist(el, &baselen, &isdir);
if (list)
{
prefix= install_extra(el, list, baselen, isdir);
el_push(el, "i");
}
popstackmark(&mark);
if (list)
return CC_REFRESH;
else
return CC_ERROR;
}
unsigned char complete_list(EditLine *el, int ch)
{
struct stackmark mark;
char **list;
setstackmark(&mark);
list= getlist(el, NULL, NULL);
if (list)
{
print_list(list);
re_goto_bottom(el);
}
popstackmark(&mark);
if (list)
{
return CC_REFRESH;
}
else
return CC_ERROR;
}
unsigned char complete_or_list(EditLine *el, int ch)
{
struct stackmark mark;
const LineInfo *lf;
char **list;
int baselen, prefix, isdir;
setstackmark(&mark);
list= getlist(el, &baselen, &isdir);
if (list)
{
prefix= install_extra(el, list, baselen, isdir);
if (prefix == baselen)
{
print_list(list);
re_goto_bottom(el);
}
}
popstackmark(&mark);
if (list)
return CC_REFRESH;
else
return CC_ERROR;
}
unsigned char complete_expand(EditLine *el, int ch)
{
printf("complete_expand\n");
return CC_ERROR;
}
static char **getlist(EditLine *el, int *baselen, int *isdir)
{
const LineInfo *lf;
const char *begin, *end;
char *dirnam, *basenam;
union node arg;
struct arglist arglist;
DIR *dir;
struct dirent *dirent;
int i, l, n;
char *p, **list;
struct strlist *slp, *nslp;
struct stat sb;
lf = el_line(el);
/* Try to find to begin and end of the word that we have to comple. */
begin= lf->cursor;
while (begin > lf->buffer && !isspace((unsigned char)begin[-1]))
begin--;
end= lf->cursor;
while (end < lf->lastchar && !isspace((unsigned char)end[0]))
end++;
*(const char **)&lf->cursor= end; /* XXX */
/* Copy the word to a string */
dirnam= stalloc(end-begin+1);
strncpy(dirnam, begin, end-begin);
dirnam[end-begin]= '\0';
/* Cut the word in two pieces: a path and a (partial) component. */
basenam= strrchr(dirnam, '/');
if (basenam)
{
basenam++;
p= stalloc(strlen(basenam) + 1);
strcpy(p, basenam);
*basenam= '\0';
basenam= p;
}
else
{
if (dirnam[0] == '~')
return getlist_tilde(dirnam);
basenam= dirnam;
dirnam= "./";
}
if (baselen)
*baselen= strlen(basenam);
arg.type= NARG;
arg.narg.next= NULL;
arg.narg.text= dirnam;
arg.narg.backquote= NULL;
arglist.list= NULL;
arglist.lastp= &arglist.list;
expandarg(&arg, &arglist, EXP_TILDE);
INTOFF;
list= NULL;
dir= opendir(arglist.list->text);
if (dir)
{
slp= NULL;
n= 0;
l= strlen(basenam);
while(dirent= readdir(dir))
{
if (strncmp(dirent->d_name, basenam, l) != 0)
continue;
if (l == 0 && dirent->d_name[0] == '.')
continue;
nslp= stalloc(sizeof(*nslp));
nslp->next= slp;
slp= nslp;
slp->text= stalloc(strlen(dirent->d_name)+1);
strcpy(slp->text, dirent->d_name);
n++;
if (n == 1 && isdir != NULL)
{
/* Try to findout whether this entry is a
* file or a directory.
*/
p= stalloc(strlen(arglist.list->text) +
strlen(dirent->d_name) + 1);
strcpy(p, arglist.list->text);
strcat(p, dirent->d_name);
if (stat(p, &sb) == -1)
printf("stat '%s' failed: %s\n",
p, strerror(errno));
if (stat(p, &sb) == 0 && S_ISDIR(sb.st_mode))
*isdir= 1;
else
*isdir= 0;
}
}
closedir(dir);
if (n != 0)
{
list= stalloc((n+1)*sizeof(*list));
for(i= 0; slp; i++, slp= slp->next)
list[i]= slp->text;
if (i != n)
error("complete'make_list: i != n");
list[i]= NULL;
qsort(list, n, sizeof(*list), vstrcmp);
}
}
INTON;
return list;
}
static char **getlist_tilde(char *prefix)
{
printf("should ~-complete '%s'\n", prefix);
return NULL;
}
static int vstrcmp(const void *v1, const void *v2)
{
return strcmp(*(char **)v1, *(char **)v2);
}
#define MAXCOLS 40
#define SEPWIDTH 4
static void print_list(char **list)
{
struct
{
int cols;
int start[MAXCOLS+1];
int width[MAXCOLS];
} best, next;
int e, i, j, l, n, o, cols, maxw, width;
int linewidth= 80;
/* Count the number of entries. */
for (n= 0; list[n]; n++)
; /* do nothing */
if (n == 0)
error("complete'print_list: n= 0");
/* Try to maximize the number of columns */
for (cols= 1; cols<= MAXCOLS; cols++)
{
next.cols= cols;
o= 0;
width= 0;
for(j= 0; j<cols; j++)
{
next.start[j]= o;
/* Number of entries in this column. */
e= (n-o)/(cols-j);
if ((n-o)%(cols-j))
e++;
maxw= 0;
for (i= 0; i<e; i++)
{
l= strlen(list[o+i]);
if (l < 6)
l= 6;
l += SEPWIDTH;
if (l > maxw)
maxw= l;
}
next.width[j]= maxw;
width += maxw;
o += e;
}
next.start[j]= o;
if (cols > 1 && width-SEPWIDTH>linewidth)
break;
best= next;
}
cols= best.cols;
e= best.start[1];
printf("\n");
for(i= 0; i<e; i++)
{
for (j= 0; j<cols; j++)
{
if (best.start[j]+i == best.start[j+1])
continue;
if (j < cols-1)
{
printf("%-*s", best.width[j],
list[best.start[j]+i]);
}
else
{
printf("%s", list[best.start[j]+i]);
}
}
if (i < e-1)
printf("\n");
}
fflush(stdout);
}
static int install_extra(EditLine *el, char **list, int baselen, int isdir)
{
int l;
char *p, **lp;
l= strlen(list[0]);
for (lp= &list[1]; *lp; lp++)
{
while(l>0)
{
if (strncmp(list[0], *lp, l) != 0)
l--;
else
break;
}
}
if (l > baselen || list[1] == NULL)
{
p= stalloc(l-baselen+2);
strncpy(p, list[0]+baselen, l-baselen);
if (list[1] == NULL)
{
p[l-baselen]= isdir ? '/' : ' ';
p[l-baselen+1]= '\0';
l++;
}
else
p[l-baselen]= '\0';
if (el_insertstr(el, p) == -1)
return -1;
}
return l;
}
/*
* $PchId: complete.c,v 1.2 2006/04/10 14:35:53 philip Exp $
*/

14
commands/ash/complete.h Normal file
View File

@@ -0,0 +1,14 @@
/*
complete.h
Created: July 1995 by Philip Homburg <philip@cs.vu.nl>
*/
unsigned char complete(EditLine *el, int ch);
unsigned char complete_list(EditLine *el, int ch);
unsigned char complete_or_list(EditLine *el, int ch);
unsigned char complete_expand(EditLine *el, int ch);
/*
* $PchId: complete.h,v 1.1 2001/05/17 07:12:05 philip Exp $
*/

View File

@@ -1,194 +0,0 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)dirent.c 5.1 (Berkeley) 3/7/91";
#endif /* not lint */
#include "shell.h" /* definitions for pointer, NULL, DIRENT, and BSD */
#if ! DIRENT
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#ifndef S_ISDIR /* macro to test for directory file */
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif
#ifdef BSD
#ifdef __STDC__
int stat(char *, struct stat *);
#else
int stat();
#endif
/*
* The BSD opendir routine doesn't check that what is being opened is a
* directory, so we have to include the check in a wrapper routine.
*/
#undef opendir
DIR *
myopendir(dirname)
char *dirname; /* name of directory */
{
struct stat statb;
if (stat(dirname, &statb) != 0 || ! S_ISDIR(statb.st_mode)) {
errno = ENOTDIR;
return NULL; /* not a directory */
}
return opendir(dirname);
}
#else /* not BSD */
/*
* Dirent routines for old style file systems.
*/
#ifdef __STDC__
pointer malloc(unsigned);
void free(pointer);
int open(char *, int, ...);
int close(int);
int fstat(int, struct stat *);
#else
pointer malloc();
void free();
int open();
int close();
int fstat();
#endif
DIR *
opendir(dirname)
char *dirname; /* name of directory */
{
register DIR *dirp; /* -> malloc'ed storage */
register int fd; /* file descriptor for read */
struct stat statb; /* result of fstat() */
#ifdef O_NDELAY
fd = open(dirname, O_RDONLY|O_NDELAY);
#else
fd = open(dirname, O_RDONLY);
#endif
if (fd < 0)
return NULL; /* errno set by open() */
if (fstat(fd, &statb) != 0 || !S_ISDIR(statb.st_mode)) {
(void)close(fd);
errno = ENOTDIR;
return NULL; /* not a directory */
}
if ((dirp = (DIR *)malloc(sizeof(DIR))) == NULL) {
(void)close(fd);
errno = ENOMEM;
return NULL; /* not enough memory */
}
dirp->dd_fd = fd;
dirp->dd_nleft = 0; /* refill needed */
return dirp;
}
int
closedir(dirp)
register DIR *dirp; /* stream from opendir() */
{
register int fd;
if (dirp == NULL) {
errno = EFAULT;
return -1; /* invalid pointer */
}
fd = dirp->dd_fd;
free((pointer)dirp);
return close(fd);
}
struct dirent *
readdir(dirp)
register DIR *dirp; /* stream from opendir() */
{
register struct direct *dp;
register char *p, *q;
register int i;
do {
if ((dirp->dd_nleft -= sizeof (struct direct)) < 0) {
if ((i = read(dirp->dd_fd,
(char *)dirp->dd_buf,
DIRBUFENT*sizeof(struct direct))) <= 0) {
if (i == 0)
errno = 0; /* unnecessary */
return NULL; /* EOF or error */
}
dirp->dd_loc = dirp->dd_buf;
dirp->dd_nleft = i - sizeof (struct direct);
}
dp = dirp->dd_loc++;
} while (dp->d_ino == 0);
dirp->dd_entry.d_ino = dp->d_ino;
/* now copy the name, nul terminating it */
p = dp->d_name;
q = dirp->dd_entry.d_name;
i = DIRSIZ;
while (--i >= 0 && *p != '\0')
*q++ = *p++;
*q = '\0';
return &dirp->dd_entry;
}
#endif /* BSD */
#endif /* DIRENT */

127
commands/ash/errmsg.c Normal file
View File

@@ -0,0 +1,127 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static char sccsid[] = "@(#)errmsg.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
#include "shell.h"
#include "output.h"
#include "errmsg.h"
#include <errno.h>
#define ALL (E_OPEN|E_CREAT|E_EXEC)
struct errname {
short errcode; /* error number */
short action; /* operation which encountered the error */
char *msg; /* text describing the error */
};
STATIC const struct errname errormsg[] = {
EINTR, ALL, "interrupted",
EACCES, ALL, "permission denied",
EIO, ALL, "I/O error",
ENOENT, E_OPEN, "no such file",
ENOENT, E_CREAT, "directory nonexistent",
ENOENT, E_EXEC, "not found",
ENOTDIR, E_OPEN, "no such file",
ENOTDIR, E_CREAT, "directory nonexistent",
ENOTDIR, E_EXEC, "not found",
EISDIR, ALL, "is a directory",
/* EMFILE, ALL, "too many open files", */
ENFILE, ALL, "file table overflow",
ENOSPC, ALL, "file system full",
#ifdef EDQUOT
EDQUOT, ALL, "disk quota exceeded",
#endif
#ifdef ENOSR
ENOSR, ALL, "no streams resources",
#endif
ENXIO, ALL, "no such device or address",
EROFS, ALL, "read-only file system",
ETXTBSY, ALL, "text busy",
#ifdef SYSV
EAGAIN, E_EXEC, "not enough memory",
#endif
ENOMEM, ALL, "not enough memory",
#ifdef ENOLINK
ENOLINK, ALL, "remote access failed"
#endif
#ifdef EMULTIHOP
EMULTIHOP, ALL, "remote access failed",
#endif
#ifdef ECOMM
ECOMM, ALL, "remote access failed",
#endif
#ifdef ESTALE
ESTALE, ALL, "remote access failed",
#endif
#ifdef ETIMEDOUT
ETIMEDOUT, ALL, "remote access failed",
#endif
#ifdef ELOOP
ELOOP, ALL, "symbolic link loop",
#endif
E2BIG, E_EXEC, "argument list too long",
#ifdef ELIBACC
ELIBACC, E_EXEC, "shared library missing",
#endif
0, 0, NULL
};
/*
* Return a string describing an error. The returned string may be a
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
char *
errmsg(e, action) {
struct errname const *ep;
static char buf[12];
for (ep = errormsg ; ep->errcode ; ep++) {
if (ep->errcode == e && (ep->action & action) != 0)
return ep->msg;
}
fmtstr(buf, sizeof buf, "error %d", e);
return buf;
}

47
commands/ash/errmsg.h Normal file
View File

@@ -0,0 +1,47 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)errmsg.h 8.1 (Berkeley) 5/31/93
*/
#define E_OPEN 01
#define E_CREAT 02
#define E_EXEC 04
#ifdef __STDC__
char *errmsg(int, int);
#else
char *errmsg();
#endif

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/error.c,v 1.25 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Errors and exceptions.
@@ -47,14 +49,14 @@ static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
#include "options.h"
#include "output.h"
#include "error.h"
#include <sys/types.h>
#include "nodes.h" /* show.h needs nodes.h */
#include "show.h"
#include "trap.h"
#include <signal.h>
#ifdef __STDC__
#include "stdarg.h"
#else
#include <varargs.h>
#endif
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
/*
@@ -62,12 +64,14 @@ static char sccsid[] = "@(#)error.c 5.1 (Berkeley) 3/7/91";
*/
struct jmploc *handler;
int exception;
volatile int suppressint;
volatile int intpending;
volatile sig_atomic_t exception;
volatile sig_atomic_t suppressint;
volatile sig_atomic_t intpending;
char *commandname;
static void exverror(int, const char *, va_list) __printf0like(2, 0);
/*
* Called to raise an exception. Since C doesn't include exceptions, we
* just do a longjmp to the exception handler. The type of exception is
@@ -75,7 +79,8 @@ char *commandname;
*/
void
exraise(e) {
exraise(int e)
{
if (handler == NULL)
abort();
exception = e;
@@ -87,69 +92,63 @@ exraise(e) {
* Called from trap.c when a SIGINT is received. (If the user specifies
* that SIGINT is to be trapped or ignored using the trap builtin, then
* this routine is not called.) Suppressint is nonzero when interrupts
* are held using the INTOFF macro. The call to _exit is necessary because
* there is a short period after a fork before the signal handlers are
* set to the appropriate value for the child. (The test for iflag is
* just defensive programming.)
* are held using the INTOFF macro. If SIGINTs are not suppressed and
* the shell is not a root shell, then we want to be terminated if we
* get here, as if we were terminated directly by a SIGINT. Arrange for
* this here.
*/
void
onint() {
if (suppressint) {
onint(void)
{
sigset_t sigset;
/*
* The !in_dotrap here is safe. The only way we can arrive here
* with in_dotrap set is that a trap handler set SIGINT to SIG_DFL
* and killed itself.
*/
if (suppressint && !in_dotrap) {
intpending++;
return;
}
intpending = 0;
#ifdef BSD
sigsetmask(0);
sigemptyset(&sigset);
sigprocmask(SIG_SETMASK, &sigset, NULL);
/*
* This doesn't seem to be needed, since main() emits a newline.
*/
#if 0
if (tcgetpgrp(0) == getpid())
write(STDERR_FILENO, "\n", 1);
#endif
if (rootshell && iflag)
exraise(EXINT);
else
_exit(128 + SIGINT);
}
void
error2(a, b)
char *a, *b;
{
error("%s: %s", a, b);
else {
signal(SIGINT, SIG_DFL);
kill(getpid(), SIGINT);
}
}
/*
* Error is called to raise the error exception. If the first argument
* Exverror is called to raise the error exception. If the first argument
* is not NULL then error prints an error message using printf style
* formatting. It then raises the error exception.
*/
#ifdef __STDC__
void
error(char *msg, ...) {
#else
void
error(va_alist)
va_dcl
{
char *msg;
#endif
va_list ap;
static void
exverror(int cond, const char *msg, va_list ap)
{
CLEAR_PENDING_INT;
INTOFF;
#ifdef __STDC__
va_start(ap, msg);
#else
va_start(ap);
msg = va_arg(ap, char *);
#endif
#if DEBUG
if (msg)
TRACE(("error(\"%s\") pid=%d\n", msg, getpid()));
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid()));
else
TRACE(("error(NULL) pid=%d\n", getpid()));
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid()));
#endif
if (msg) {
if (commandname)
@@ -157,96 +156,30 @@ error(va_alist)
doformat(&errout, msg, ap);
out2c('\n');
}
va_end(ap);
flushall();
exraise(EXERROR);
exraise(cond);
}
#ifdef notdef /* These strange error messages only confuse. -- kjb */
/*
* Table of error messages.
*/
struct errname {
short errcode; /* error number */
short action; /* operation which encountered the error */
char *msg; /* text describing the error */
};
#define ALL (E_OPEN|E_CREAT|E_EXEC)
STATIC const struct errname errormsg[] = {
EINTR, ALL, "interrupted",
EACCES, ALL, "permission denied",
EIO, ALL, "I/O error",
ENOENT, E_OPEN, "no such file",
ENOENT, E_CREAT, "directory nonexistent",
ENOENT, E_EXEC, "not found",
ENOTDIR, E_OPEN, "no such file",
ENOTDIR, E_CREAT, "directory nonexistent",
ENOTDIR, E_EXEC, "not found",
ENOEXEC, ALL, "not an executable",
EISDIR, ALL, "is a directory",
/* EMFILE, ALL, "too many open files", */
ENFILE, ALL, "file table overflow",
ENOSPC, ALL, "file system full",
#ifdef EDQUOT
EDQUOT, ALL, "disk quota exceeded",
#endif
#ifdef ENOSR
ENOSR, ALL, "no streams resources",
#endif
ENXIO, ALL, "no such device or address",
EROFS, ALL, "read-only file system",
ETXTBSY, ALL, "text busy",
#ifdef SYSV
EAGAIN, E_EXEC, "not enough memory",
#endif
ENOMEM, ALL, "not enough memory",
#ifdef ENOLINK
ENOLINK, ALL, "remote access failed",
#endif
#ifdef EMULTIHOP
EMULTIHOP, ALL, "remote access failed",
#endif
#ifdef ECOMM
ECOMM, ALL, "remote access failed",
#endif
#ifdef ESTALE
ESTALE, ALL, "remote access failed",
#endif
#ifdef ETIMEDOUT
ETIMEDOUT, ALL, "remote access failed",
#endif
#ifdef ELOOP
ELOOP, ALL, "symbolic link loop",
#endif
E2BIG, E_EXEC, "argument list too long",
#ifdef ELIBACC
ELIBACC, E_EXEC, "shared library missing",
#endif
0, 0, NULL
};
/*
* Return a string describing an error. The returned string may be a
* pointer to a static buffer that will be overwritten on the next call.
* Action describes the operation that got the error.
*/
char *
errmsg(e, action) {
const struct errname *ep;
static char buf[12];
for (ep = errormsg ; ep->errcode ; ep++) {
if (ep->errcode == e && (ep->action & action) != 0)
return ep->msg;
}
fmtstr(buf, sizeof buf, "error %d", e);
return buf;
void
error(const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
exverror(EXERROR, msg, ap);
va_end(ap);
}
#endif
void
exerror(int cond, const char *msg, ...)
{
va_list ap;
va_start(ap, msg);
exverror(cond, msg, ap);
va_end(ap);
}
/*
* $PchId: error.c,v 1.5 2006/04/10 14:36:23 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,41 +29,35 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)error.h 5.1 (Berkeley) 3/7/91
* @(#)error.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/error.h,v 1.17 2004/04/06 20:06:51 markm Exp $
*/
/*
* Types of operations (passed to the errmsg routine).
*/
#define E_OPEN 01 /* opening a file */
#define E_CREAT 02 /* creating a file */
#define E_EXEC 04 /* executing a program */
/*
* We enclose jmp_buf in a structure so that we can declare pointers to
* jump locations. The global variable handler contains the location to
* jump to when an exception occurs, and the global variable exception
* contains a code identifying the exeception. To implement nested
* contains a code identifying the exception. To implement nested
* exception handlers, the user should save the value of handler on entry
* to an inner scope, set handler to point to a jmploc structure for the
* inner scope, and restore handler on exit from the scope.
*/
#include <setjmp.h>
#include <signal.h>
struct jmploc {
jmp_buf loc;
};
extern struct jmploc *handler;
extern int exception;
extern volatile sig_atomic_t exception;
/* exceptions */
#define EXINT 0 /* SIGINT received */
#define EXERROR 1 /* a generic error */
#define EXSHELLPROC 2 /* execute a shell procedure */
#define EXEXEC 3 /* command execution failed */
/*
@@ -77,32 +67,21 @@ extern int exception;
* more fun than worrying about efficiency and portability. :-))
*/
extern volatile int suppressint;
extern volatile int intpending;
extern char *commandname; /* name of command--printed on error */
extern volatile sig_atomic_t suppressint;
extern volatile sig_atomic_t intpending;
#define INTOFF suppressint++
#define INTON if (--suppressint == 0 && intpending) onint(); else
#define INTON { if (--suppressint == 0 && intpending) onint(); }
#define FORCEINTON {suppressint = 0; if (intpending) onint();}
#define CLEAR_PENDING_INT intpending = 0
#define int_pending() intpending
#ifdef __STDC__
#define __printf0like(a,b)
void exraise(int);
void onint(void);
void error2(char *, char *);
void error(char *, ...);
char *errmsg(int, int);
#else
void exraise();
void onint();
void error2();
void error();
char *errmsg();
#endif
/* Errmsg uses confusingly different messages. Prefer strerror(). -- kjb */
#define errmsg(errno, action) strerror(errno)
void error(const char *, ...) __printf0like(1, 2);
void exerror(int, const char *, ...) __printf0like(2, 3);
/*
@@ -111,6 +90,12 @@ char *errmsg();
*/
#ifdef BSD
#ifndef __minix
#define setjmp(jmploc) _setjmp(jmploc)
#define longjmp(jmploc, val) _longjmp(jmploc, val)
#endif
#endif
/*
* $PchId: error.h,v 1.5 2006/04/10 14:36:43 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,23 @@
*/
#ifndef lint
static char sccsid[] = "@(#)eval.c 5.3 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/eval.c,v 1.42 2004/04/06 20:06:51 markm Exp $");
*/
#ifndef NO_PATHS_H
#include <paths.h>
#endif
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h> /* For WIFSIGNALED(status) */
#include <errno.h>
/*
* Evaluate a command.
@@ -59,22 +70,21 @@ static char sccsid[] = "@(#)eval.c 5.3 (Berkeley) 4/12/91";
#include "var.h"
#include "memalloc.h"
#include "error.h"
#include "show.h"
#include "mystring.h"
#include <sys/types.h>
#include <signal.h>
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#ifndef _PATH_STDPATH
#define _PATH_STDPATH "/usr/bin:/bin:/usr/sbin:/sbin:"
#endif
/* flags in argument to evaltree */
#define EV_EXIT 01 /* exit after evaluating tree */
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */
#define EV_BACKCMD 04 /* command executing within back quotes */
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
MKINIT int evalskip; /* set if we are skipping commands */
STATIC int skipcount; /* number of levels to skip */
MKINIT int loopnest; /* current loop nesting level */
@@ -87,7 +97,6 @@ int exitstatus; /* exit status of last command */
int oexitstatus; /* saved exit status */
#ifdef __STDC__
STATIC void evalloop(union node *);
STATIC void evalfor(union node *);
STATIC void evalcase(union node *, int);
@@ -96,17 +105,6 @@ STATIC void expredir(union node *);
STATIC void evalpipe(union node *);
STATIC void evalcommand(union node *, int, struct backcmd *);
STATIC void prehash(union node *);
#else
STATIC void evalloop();
STATIC void evalfor();
STATIC void evalcase();
STATIC void evalsubshell();
STATIC void expredir();
STATIC void evalpipe();
STATIC void evalcommand();
STATIC void prehash();
#endif
/*
@@ -130,11 +128,11 @@ SHELLPROC {
/*
* The eval commmand.
* The eval command.
*/
evalcmd(argc, argv)
char **argv;
int
evalcmd(int argc, char **argv)
{
char *p;
char *concat;
@@ -166,9 +164,8 @@ evalcmd(argc, argv)
*/
void
evalstring(s)
char *s;
{
evalstring(char *s)
{
union node *n;
struct stackmark smark;
@@ -190,14 +187,17 @@ evalstring(s)
*/
void
evaltree(n, flags)
union node *n;
{
evaltree(union node *n, int flags)
{
if (n == NULL) {
TRACE(("evaltree(NULL) called\n"));
return;
exitstatus = 0;
goto out;
}
TRACE(("evaltree(0x%x: %d) called\n", (int)n, n->type));
#if !defined(NO_HISTORY) && !defined(EDITLINE)
displayhist = 1; /* show history substitutions done with fc */
#endif
TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type));
switch (n->type) {
case NSEMI:
evaltree(n->nbinary.ch1, 0);
@@ -207,8 +207,9 @@ evaltree(n, flags)
break;
case NAND:
evaltree(n->nbinary.ch1, EV_TESTED);
if (evalskip || exitstatus != 0)
if (evalskip || exitstatus != 0) {
goto out;
}
evaltree(n->nbinary.ch2, flags);
break;
case NOR:
@@ -230,19 +231,15 @@ evaltree(n, flags)
evalsubshell(n, flags);
break;
case NIF: {
int status = 0;
evaltree(n->nif.test, EV_TESTED);
if (evalskip)
goto out;
if (exitstatus == 0) {
if (exitstatus == 0)
evaltree(n->nif.ifpart, flags);
status = exitstatus;
} else if (n->nif.elsepart) {
else if (n->nif.elsepart)
evaltree(n->nif.elsepart, flags);
status = exitstatus;
}
exitstatus = status;
else
exitstatus = 0;
break;
}
case NWHILE:
@@ -259,6 +256,11 @@ evaltree(n, flags)
defun(n->narg.text, n->narg.next);
exitstatus = 0;
break;
case NNOT:
evaltree(n->nnot.com, EV_TESTED);
exitstatus = !exitstatus;
break;
case NPIPE:
evalpipe(n);
break;
@@ -273,18 +275,16 @@ evaltree(n, flags)
out:
if (pendingsigs)
dotrap();
if ((flags & EV_EXIT) || (eflag && exitstatus
&& !(flags & EV_TESTED) && (n->type == NCMD ||
n->type == NSUBSHELL))) {
if ((flags & EV_EXIT) || (eflag && exitstatus
&& !(flags & EV_TESTED) && (n->type == NCMD ||
n->type == NSUBSHELL)))
exitshell(exitstatus);
}
}
STATIC void
evalloop(n)
union node *n;
{
evalloop(union node *n)
{
int status;
loopnest++;
@@ -319,9 +319,8 @@ skipping: if (evalskip == SKIPCONT && --skipcount <= 0) {
STATIC void
evalfor(n)
union node *n;
{
evalfor(union node *n)
{
struct arglist arglist;
union node *argp;
struct strlist *sp;
@@ -331,7 +330,7 @@ evalfor(n)
arglist.lastp = &arglist.list;
for (argp = n->nfor.args ; argp ; argp = argp->narg.next) {
oexitstatus = exitstatus;
expandarg(argp, &arglist, 1);
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
if (evalskip)
goto out;
}
@@ -360,9 +359,8 @@ out:
STATIC void
evalcase(n, flags)
union node *n;
{
evalcase(union node *n, int flags)
{
union node *cp;
union node *patp;
struct arglist arglist;
@@ -370,8 +368,8 @@ evalcase(n, flags)
setstackmark(&smark);
arglist.lastp = &arglist.list;
oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, 0);
oexitstatus = exitstatus;
expandarg(n->ncase.expr, &arglist, EXP_TILDE);
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) {
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) {
if (casematch(patp, arglist.list->text)) {
@@ -393,9 +391,8 @@ out:
*/
STATIC void
evalsubshell(n, flags)
union node *n;
{
evalsubshell(union node *n, int flags)
{
struct job *jp;
int backgnd = (n->type == NBACKGND);
@@ -409,7 +406,7 @@ evalsubshell(n, flags)
}
if (! backgnd) {
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, (int *)NULL);
INTON;
}
}
@@ -421,20 +418,30 @@ evalsubshell(n, flags)
*/
STATIC void
expredir(n)
union node *n;
{
register union node *redir;
expredir(union node *n)
{
union node *redir;
for (redir = n ; redir ; redir = redir->nfile.next) {
struct arglist fn;
fn.lastp = &fn.list;
oexitstatus = exitstatus;
if (redir->type == NFROM
|| redir->type == NTO
|| redir->type == NAPPEND) {
struct arglist fn;
fn.lastp = &fn.list;
expandarg(redir->nfile.fname, &fn, 0);
switch (redir->type) {
case NFROM:
case NTO:
case NFROMTO:
case NAPPEND:
case NCLOBBER:
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR);
redir->nfile.expfname = fn.list->text;
break;
case NFROMFD:
case NTOFD:
if (redir->ndup.vname) {
expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE);
fixredir(redir, fn.list->text, 1);
}
break;
}
}
}
@@ -449,16 +456,15 @@ expredir(n)
*/
STATIC void
evalpipe(n)
union node *n;
{
evalpipe(union node *n)
{
struct job *jp;
struct nodelist *lp;
int pipelen;
int prevfd;
int pip[2];
TRACE(("evalpipe(0x%x) called\n", (int)n));
TRACE(("evalpipe(0x%lx) called\n", (long)n));
pipelen = 0;
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next)
pipelen++;
@@ -471,21 +477,20 @@ evalpipe(n)
if (lp->next) {
if (pipe(pip) < 0) {
close(prevfd);
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
}
}
if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) {
INTON;
if (prevfd > 0) {
close(0);
copyfd(prevfd, 0);
dup2(prevfd, 0);
close(prevfd);
}
if (pip[1] >= 0) {
close(pip[0]);
if (!(prevfd >= 0 && pip[0] == 0))
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
}
@@ -499,7 +504,7 @@ evalpipe(n)
INTON;
if (n->npipe.backgnd == 0) {
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, (int *)NULL);
TRACE(("evalpipe: job done exit status %d\n", exitstatus));
INTON;
}
@@ -515,10 +520,8 @@ evalpipe(n)
*/
void
evalbackcmd(n, result)
union node *n;
struct backcmd *result;
{
evalbackcmd(union node *n, struct backcmd *result)
{
int pip[2];
struct job *jp;
struct stackmark smark; /* unnecessary */
@@ -529,21 +532,22 @@ evalbackcmd(n, result)
result->nleft = 0;
result->jp = NULL;
if (n == NULL) {
/* `` */
} else
exitstatus = 0;
goto out;
}
if (n->type == NCMD) {
exitstatus = oexitstatus;
exitstatus = oexitstatus;
evalcommand(n, EV_BACKCMD, result);
} else {
exitstatus = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
jp = makejob(n, 1);
if (forkshell(jp, n, FORK_NOJOB) == 0) {
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
evaltree(n, EV_EXIT);
@@ -552,8 +556,9 @@ evalbackcmd(n, result)
result->fd = pip[0];
result->jp = jp;
}
out:
popstackmark(&smark);
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n",
TRACE(("evalbackcmd done: fd=%d buf=%p nleft=%d jp=%p\n",
result->fd, result->buf, result->nleft, result->jp));
}
@@ -564,10 +569,8 @@ evalbackcmd(n, result)
*/
STATIC void
evalcommand(cmd, flags, backcmd)
union node *cmd;
struct backcmd *backcmd;
{
evalcommand(union node *cmd, int flags, struct backcmd *backcmd)
{
struct stackmark smark;
union node *argp;
struct arglist arglist;
@@ -577,7 +580,6 @@ evalcommand(cmd, flags, backcmd)
char **envp;
int varflag;
struct strlist *sp;
register char *p;
int mode;
int pip[2];
struct cmdentry cmdentry;
@@ -589,27 +591,38 @@ evalcommand(cmd, flags, backcmd)
struct localvar *volatile savelocalvars;
volatile int e;
char *lastarg;
int realstatus;
int do_clearcmdentry;
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &argv;
(void) &argc;
(void) &lastarg;
(void) &flags;
(void) &do_clearcmdentry;
#endif
/* First expand the arguments. */
TRACE(("evalcommand(0x%x, %d) called\n", (int)cmd, flags));
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags));
setstackmark(&smark);
arglist.lastp = &arglist.list;
varlist.lastp = &varlist.list;
varflag = 1;
oexitstatus = exitstatus;
do_clearcmdentry = 0;
oexitstatus = exitstatus;
exitstatus = 0;
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) {
p = argp->narg.text;
char *p = argp->narg.text;
if (varflag && is_name(*p)) {
do {
p++;
} while (is_in_name(*p));
if (*p == '=') {
expandarg(argp, &varlist, 0);
expandarg(argp, &varlist, EXP_VARTILDE);
continue;
}
}
expandarg(argp, &arglist, 1);
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE);
varflag = 0;
}
*arglist.lastp = NULL;
@@ -619,8 +632,11 @@ evalcommand(cmd, flags, backcmd)
for (sp = arglist.list ; sp ; sp = sp->next)
argc++;
argv = stalloc(sizeof (char *) * (argc + 1));
for (sp = arglist.list ; sp ; sp = sp->next)
for (sp = arglist.list ; sp ; sp = sp->next) {
TRACE(("evalcommand arg: %s\n", sp->text));
*argv++ = sp->text;
}
*argv = NULL;
lastarg = NULL;
if (iflag && funcnest == 0 && argc > 0)
@@ -628,7 +644,7 @@ evalcommand(cmd, flags, backcmd)
argv -= argc;
/* Print the command if xflag is set. */
if (xflag == 1) {
if (xflag) {
outc('+', &errout);
for (sp = varlist.list ; sp ; sp = sp->next) {
outc(' ', &errout);
@@ -647,11 +663,42 @@ evalcommand(cmd, flags, backcmd)
cmdentry.cmdtype = CMDBUILTIN;
cmdentry.u.index = BLTINCMD;
} else {
find_command(argv[0], &cmdentry, 1);
static const char PATH[] = "PATH=";
char *path = pathval();
/*
* Modify the command lookup path, if a PATH= assignment
* is present
*/
for (sp = varlist.list ; sp ; sp = sp->next)
if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) {
path = sp->text + sizeof(PATH) - 1;
/*
* On `PATH=... command`, we need to make
* sure that the command isn't using the
* non-updated hash table of the outer PATH
* setting and we need to make sure that
* the hash table isn't filled with items
* from the temporary setting.
*
* It would be better to forbit using and
* updating the table while this command
* runs, by the command finding mechanism
* is heavily integrated with hash handling,
* so we just delete the hash before and after
* the command runs. Partly deleting like
* changepatch() does doesn't seem worth the
* bookinging effort, since most such runs add
* directories in front of the new PATH.
*/
clearcmdentry(0);
do_clearcmdentry = 1;
}
find_command(argv[0], &cmdentry, 1, path);
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */
exitstatus = 2;
exitstatus = 127;
flushout(&errout);
popstackmark(&smark);
return;
}
/* implement the bltin builtin here */
@@ -662,9 +709,8 @@ evalcommand(cmd, flags, backcmd)
break;
if ((cmdentry.u.index = find_builtin(*argv)) < 0) {
outfmt(&errout, "%s: not found\n", *argv);
exitstatus = 2;
exitstatus = 127;
flushout(&errout);
popstackmark(&smark);
return;
}
if (cmdentry.u.index != BLTINCMD)
@@ -675,17 +721,21 @@ evalcommand(cmd, flags, backcmd)
/* Fork off a child process if necessary. */
if (cmd->ncmd.backgnd
|| cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0
|| (flags & EV_BACKCMD) != 0
|| (cmdentry.cmdtype == CMDNORMAL
&& ((flags & EV_EXIT) == 0 || Tflag))
|| ((flags & EV_BACKCMD) != 0
&& (cmdentry.cmdtype != CMDBUILTIN
|| cmdentry.u.index == CDCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD)) {
|| cmdentry.u.index == EVALCMD))
|| (cmdentry.cmdtype == CMDBUILTIN &&
cmdentry.u.index == COMMANDCMD)) {
jp = makejob(cmd, 1);
mode = cmd->ncmd.backgnd;
if (flags & EV_BACKCMD) {
mode = FORK_NOJOB;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
}
if (forkshell(jp, cmd, mode) != 0)
goto parent; /* at end of routine */
@@ -693,8 +743,7 @@ evalcommand(cmd, flags, backcmd)
FORCEINTON;
close(pip[0]);
if (pip[1] != 1) {
close(1);
copyfd(pip[1], 1);
dup2(pip[1], 1);
close(pip[1]);
}
}
@@ -704,10 +753,13 @@ evalcommand(cmd, flags, backcmd)
/* This is the child process if a fork occurred. */
/* Execute the command. */
if (cmdentry.cmdtype == CMDFUNCTION) {
#if DEBUG
trputs("Shell function: "); trargs(argv);
#endif
redirect(cmd->ncmd.redirect, REDIR_PUSH);
saveparam = shellparam;
shellparam.malloc = 0;
shellparam.reset = 1;
shellparam.nparam = argc - 1;
shellparam.p = argv + 1;
shellparam.optnext = NULL;
@@ -752,7 +804,9 @@ evalcommand(cmd, flags, backcmd)
if (flags & EV_EXIT)
exitshell(exitstatus);
} else if (cmdentry.cmdtype == CMDBUILTIN) {
#if DEBUG
trputs("builtin command: "); trargs(argv);
#endif
mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH;
if (flags == EV_BACKCMD) {
memout.nleft = 0;
@@ -777,6 +831,7 @@ evalcommand(cmd, flags, backcmd)
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv);
flushall();
cmddone:
cmdenviron = NULL;
out1 = &output;
out2 = &errout;
freestdout();
@@ -788,10 +843,15 @@ cmddone:
}
handler = savehandler;
if (e != -1) {
if (e != EXERROR || cmdentry.u.index == BLTINCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD
|| cmdentry.u.index == EXECCMD)
if ((e != EXERROR && e != EXEXEC)
|| cmdentry.u.index == BLTINCMD
|| cmdentry.u.index == DOTCMD
|| cmdentry.u.index == EVALCMD
#ifndef NO_HISTORY
|| cmdentry.u.index == HISTCMD
#endif
|| cmdentry.u.index == EXECCMD
|| cmdentry.u.index == COMMANDCMD)
exraise(e);
FORCEINTON;
}
@@ -803,19 +863,15 @@ cmddone:
memout.buf = NULL;
}
} else {
#if DEBUG
trputs("normal command: "); trargs(argv);
#endif
clearredir();
redirect(cmd->ncmd.redirect, 0);
if (varlist.list) {
p = stalloc(strlen(pathval()) + 1);
scopy(pathval(), p);
} else {
p = pathval();
}
for (sp = varlist.list ; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
envp = environment();
shellexec(argv, envp, p, cmdentry.u.index);
shellexec(argv, envp, pathval(), cmdentry.u.index);
/*NOTREACHED*/
}
goto out;
@@ -823,8 +879,12 @@ cmddone:
parent: /* parent process gets here (if we forked) */
if (mode == 0) { /* argument to fork */
INTOFF;
exitstatus = waitforjob(jp);
exitstatus = waitforjob(jp, &realstatus);
INTON;
if (iflag && loopnest > 0 && WIFSIGNALED(realstatus)) {
evalskip = SKIPBREAK;
skipcount = loopnest;
}
} else if (mode == 2) {
backcmd->fd = pip[0];
close(pip[1]);
@@ -834,6 +894,8 @@ parent: /* parent process gets here (if we forked) */
out:
if (lastarg)
setvar("_", lastarg, 0);
if (do_clearcmdentry)
clearcmdentry(0);
popstackmark(&smark);
}
@@ -847,13 +909,14 @@ out:
*/
STATIC void
prehash(n)
union node *n;
{
prehash(union node *n)
{
struct cmdentry entry;
if (n->type == NCMD && goodname(n->ncmd.args->narg.text))
find_command(n->ncmd.args->narg.text, &entry, 0);
if (n->type == NCMD && n->ncmd.args)
if (goodname(n->ncmd.args->narg.text))
find_command(n->ncmd.args->narg.text, &entry, 0,
pathval());
}
@@ -868,8 +931,14 @@ prehash(n)
* specified variables.
*/
bltincmd(argc, argv) char **argv; {
int
bltincmd(int argc __unused, char **argv __unused)
{
listsetvar(cmdenviron);
/*
* Preserve exitstatus of a previous possible redirection
* as POSIX mandates
*/
return exitstatus;
}
@@ -885,12 +954,11 @@ bltincmd(argc, argv) char **argv; {
* in the standard shell so we don't make it one here.
*/
breakcmd(argc, argv) char **argv; {
int n;
int
breakcmd(int argc, char **argv)
{
int n = argc > 1 ? number(argv[1]) : 1;
n = 1;
if (argc > 1)
n = number(argv[1]);
if (n > loopnest)
n = loopnest;
if (n > 0) {
@@ -900,40 +968,108 @@ breakcmd(argc, argv) char **argv; {
return 0;
}
/*
* The `command' command.
*/
int
commandcmd(int argc, char **argv)
{
static char stdpath[] = _PATH_STDPATH;
struct jmploc loc, *old;
struct strlist *sp;
char *path;
int ch;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
path = pathval();
optind = optreset = 1;
opterr = 0;
while ((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
case 'p':
path = stdpath;
break;
case '?':
default:
error("unknown option: -%c", optopt);
}
}
argc -= optind;
argv += optind;
if (argc != 0) {
old = handler;
handler = &loc;
if (setjmp(handler->loc) == 0)
shellexec(argv, environment(), path, 0);
handler = old;
if (exception == EXEXEC)
exit(exerrno);
exraise(exception);
}
/*
* Do nothing successfully if no command was specified;
* ksh also does this.
*/
exit(0);
}
/*
* The return command.
*/
returncmd(argc, argv) char **argv; {
int ret;
int
returncmd(int argc, char **argv)
{
int ret = argc > 1 ? number(argv[1]) : oexitstatus;
ret = oexitstatus;
if (argc > 1)
ret = number(argv[1]);
if (funcnest) {
evalskip = SKIPFUNC;
skipcount = 1;
} else {
/* skip the rest of the file */
evalskip = SKIPFILE;
skipcount = 1;
}
return ret;
}
truecmd(argc, argv) char **argv; {
return strcmp(argv[0], "false") == 0 ? 1 : 0;
int
falsecmd(int argc __unused, char **argv __unused)
{
return 1;
}
execcmd(argc, argv) char **argv; {
int
truecmd(int argc __unused, char **argv __unused)
{
return 0;
}
int
execcmd(int argc, char **argv)
{
if (argc > 1) {
struct strlist *sp;
iflag = 0; /* exit on error */
setinteractive(0);
#if JOBS
jflag = 0;
setjobctl(0);
#endif
mflag = 0;
optschanged();
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(sp->text, VEXPORT|VSTACK);
shellexec(argv + 1, environment(), pathval(), 0);
}
return 0;
}
/*
* $PchId: eval.c,v 1.7 2006/04/10 14:46:14 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)eval.h 5.2 (Berkeley) 4/12/91
* @(#)eval.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/eval.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
extern char *commandname; /* currently executing command */
@@ -48,18 +45,30 @@ struct backcmd { /* result of evalbackcmd */
struct job *jp; /* job structure for command */
};
#ifdef __STDC__
int evalcmd(int, char **);
void evalstring(char *);
union node; /* BLETCH for ansi C */
void evaltree(union node *, int);
void evalbackcmd(union node *, struct backcmd *);
#else
void evalstring();
void evaltree();
void evalbackcmd();
#endif
int bltincmd(int, char **);
int breakcmd(int, char **);
int returncmd(int, char **);
int falsecmd(int, char **);
int truecmd(int, char **);
int execcmd(int, char **);
int commandcmd(int, char **);
/* in_function returns nonzero if we are currently evaluating a function */
#define in_function() funcnest
extern int funcnest;
extern int evalskip;
/* reasons for skipping commands (see comment on breakcmd routine) */
#define SKIPBREAK 1
#define SKIPCONT 2
#define SKIPFUNC 3
#define SKIPFILE 4
/*
* $PchId: eval.h,v 1.3 2006/03/30 15:39:25 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,21 @@
*/
#ifndef lint
static char sccsid[] = "@(#)exec.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/exec.c,v 1.24.2.1 2004/09/30 04:41:55 des Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
/*
* When commands are first encountered, they are entered in a hash table.
@@ -64,11 +73,9 @@ static char sccsid[] = "@(#)exec.c 5.2 (Berkeley) 3/13/91";
#include "error.h"
#include "init.h"
#include "mystring.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include "show.h"
#include "jobs.h"
#include "alias.h"
#define CMDTABLESIZE 31 /* should be prime */
@@ -87,23 +94,14 @@ struct tblentry {
STATIC struct tblentry *cmdtable[CMDTABLESIZE];
STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */
int exerrno = 0; /* Last exec error */
#ifdef __STDC__
STATIC void tryexec(char *, char **, char **);
STATIC void execinterp(char **, char **);
STATIC void printentry(struct tblentry *);
STATIC void clearcmdentry(int);
STATIC void printentry(struct tblentry *, int);
STATIC struct tblentry *cmdlookup(char *, int);
STATIC void delete_cmd_entry(void);
#else
STATIC void tryexec();
STATIC void execinterp();
STATIC void printentry();
STATIC void clearcmdentry();
STATIC struct tblentry *cmdlookup();
STATIC void delete_cmd_entry();
#endif
STATIC void addcmdentry(char *, struct cmdentry *);
@@ -113,10 +111,8 @@ STATIC void delete_cmd_entry();
*/
void
shellexec(argv, envp, path, index)
char **argv, **envp;
char *path;
{
shellexec(char **argv, char **envp, char *path, int index)
{
char *cmdname;
int e;
@@ -134,40 +130,37 @@ shellexec(argv, envp, path, index)
stunalloc(cmdname);
}
}
error2(argv[0], errmsg(e, E_EXEC));
/* Map to POSIX errors */
switch (e) {
case EACCES:
exerrno = 126;
break;
case ENOENT:
exerrno = 127;
break;
default:
exerrno = 2;
break;
}
if (e == ENOENT || e == ENOTDIR)
exerror(EXEXEC, "%s: not found", argv[0]);
exerror(EXEXEC, "%s: %s", argv[0], strerror(e));
}
STATIC void
tryexec(cmd, argv, envp)
char *cmd;
char **argv;
char **envp;
{
tryexec(char *cmd, char **argv, char **envp)
{
int e;
char *p;
#ifdef SYSV
do {
execve(cmd, argv, envp);
} while (errno == EINTR);
#else
execve(cmd, argv, envp);
#endif
#if HASHBANG
#if !__minix_vmd
e = errno;
if (e == ENOEXEC) {
initshellproc();
setinputfile(cmd, 0);
commandname = arg0 = savestr(argv[0]);
#ifndef BSD
pgetc(); pungetc(); /* fill up input buffer */
p = parsenextc;
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') {
argv[0] = cmd;
execinterp(argv, envp);
}
#endif
setparam(argv + 1);
exraise(EXSHELLPROC);
/*NOTREACHED*/
@@ -176,88 +169,6 @@ tryexec(cmd, argv, envp)
#endif
}
#if !defined(BSD) && HASHBANG
/*
* Execute an interpreter introduced by "#!", for systems where this
* feature has not been built into the kernel. If the interpreter is
* the shell, return (effectively ignoring the "#!"). If the execution
* of the interpreter fails, exit.
*
* This code peeks inside the input buffer in order to avoid actually
* reading any input. It would benefit from a rewrite.
*/
#define NEWARGS 5
STATIC void
execinterp(argv, envp)
char **argv, **envp;
{
int n;
char *inp;
char *outp;
char c;
char *p;
char **ap;
char *newargs[NEWARGS];
int i;
char **ap2;
char **new;
n = parsenleft - 2;
inp = parsenextc + 2;
ap = newargs;
for (;;) {
while (--n >= 0 && (*inp == ' ' || *inp == '\t'))
inp++;
if (n < 0)
goto bad;
if ((c = *inp++) == '\n')
break;
if (ap == &newargs[NEWARGS])
bad: error("Bad #! line");
STARTSTACKSTR(outp);
do {
STPUTC(c, outp);
} while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n');
STPUTC('\0', outp);
n++, inp--;
*ap++ = grabstackstr(outp);
}
#if !__minix
if (ap == newargs + 1) { /* if no args, maybe no exec is needed */
p = newargs[0];
for (;;) {
if (equal(p, "sh") || equal(p, "ash")) {
return;
}
while (*p != '/') {
if (*p == '\0')
goto break2;
p++;
}
p++;
}
break2:;
}
#endif
i = (char *)ap - (char *)newargs; /* size in bytes */
if (i == 0)
error("Bad #! line");
for (ap2 = argv ; *ap2++ != NULL ; );
new = ckmalloc(i + ((char *)ap2 - (char *)argv));
ap = newargs, ap2 = new;
while ((i -= sizeof (char **)) >= 0)
*ap2++ = *ap++;
ap = argv;
while (*ap2++ = *ap++);
shellexec(new, envp, pathval(), 0);
}
#endif
/*
* Do a path search. The variable path (passed by reference) should be
* set to the start of the path before the first call; padvance will update
@@ -271,11 +182,9 @@ break2:;
char *pathopt;
char *
padvance(path, name)
char **path;
char *name;
{
register char *p, *q;
padvance(char **path, char *name)
{
char *p, *q;
char *start;
int len;
@@ -288,7 +197,7 @@ padvance(path, name)
growstackblock();
q = stackblock();
if (p != start) {
bcopy(start, q, p - start);
memcpy(q, start, p - start);
q += p - start;
*q++ = '/';
}
@@ -310,7 +219,9 @@ padvance(path, name)
/*** Command hashing code ***/
hashcmd(argc, argv) char **argv; {
int
hashcmd(int argc __unused, char **argv __unused)
{
struct tblentry **pp;
struct tblentry *cmdp;
int c;
@@ -318,14 +229,6 @@ hashcmd(argc, argv) char **argv; {
struct cmdentry entry;
char *name;
if (argc <= 1) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
printentry(cmdp);
}
}
return 0;
}
verbose = 0;
while ((c = nextopt("rv")) != '\0') {
if (c == 'r') {
@@ -334,16 +237,28 @@ hashcmd(argc, argv) char **argv; {
verbose++;
}
}
if (*argptr == NULL) {
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (cmdp->cmdtype == CMDNORMAL)
printentry(cmdp, verbose);
}
}
return 0;
}
while ((name = *argptr) != NULL) {
if ((cmdp = cmdlookup(name, 0)) != NULL
&& (cmdp->cmdtype == CMDNORMAL
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)))
delete_cmd_entry();
find_command(name, &entry, 1);
find_command(name, &entry, 1, pathval());
if (verbose) {
if (entry.cmdtype != CMDUNKNOWN) { /* if no error msg */
cmdp = cmdlookup(name, 0);
printentry(cmdp);
if (cmdp != NULL)
printentry(cmdp, verbose);
else
outfmt(&errout, "%s: not found\n", name);
}
flushall();
}
@@ -354,9 +269,8 @@ hashcmd(argc, argv) char **argv; {
STATIC void
printentry(cmdp)
struct tblentry *cmdp;
{
printentry(struct tblentry *cmdp, int verbose)
{
int index;
char *path;
char *name;
@@ -373,6 +287,14 @@ printentry(cmdp)
out1fmt("builtin %s", cmdp->cmdname);
} else if (cmdp->cmdtype == CMDFUNCTION) {
out1fmt("function %s", cmdp->cmdname);
if (verbose) {
INTOFF;
name = commandtext(cmdp->param.func);
out1c(' ');
out1str(name);
ckfree(name);
INTON;
}
#if DEBUG
} else {
error("internal error: cmdtype %d", cmdp->cmdtype);
@@ -391,14 +313,11 @@ printentry(cmdp)
*/
void
find_command(name, entry, printerr)
char *name;
struct cmdentry *entry;
{
find_command(char *name, struct cmdentry *entry, int printerr, char *path)
{
struct tblentry *cmdp;
int index;
int prev;
char *path;
char *fullname;
struct stat statb;
int e;
@@ -434,7 +353,6 @@ find_command(name, entry, printerr)
prev = cmdp->param.index;
}
path = pathval();
e = ENOENT;
index = -1;
loop:
@@ -464,17 +382,13 @@ loop:
TRACE(("searchexec \"%s\": no change\n", name));
goto success;
}
while (stat(fullname, &statb) < 0) {
#ifdef SYSV
if (errno == EINTR)
continue;
#endif
if (stat(fullname, &statb) < 0) {
if (errno != ENOENT && errno != ENOTDIR)
e = errno;
goto loop;
}
e = EACCES; /* if we fail, this will be the error */
if ((statb.st_mode & S_IFMT) != S_IFREG)
if (!S_ISREG(statb.st_mode))
goto loop;
if (pathopt) { /* this is a %func directory */
stalloc(strlen(fullname) + 1);
@@ -484,6 +398,7 @@ loop:
stunalloc(fullname);
goto success;
}
#ifdef notdef
if (statb.st_uid == geteuid()) {
if ((statb.st_mode & 0100) == 0)
goto loop;
@@ -491,23 +406,10 @@ loop:
if ((statb.st_mode & 010) == 0)
goto loop;
} else {
#if __minix_vmd || defined(BSD)
gid_t group_list[NGROUPS_MAX];
int ngroups, i;
ngroups = getgroups(NGROUPS_MAX, group_list);
for (i = 0; i < ngroups; i++) {
if (statb.st_gid == group_list[i]) break;
}
if (i < ngroups) {
if ((statb.st_mode & 010) == 0)
goto loop;
} else
#endif
if ((statb.st_mode & 01) == 0)
goto loop;
}
#endif
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname));
INTOFF;
cmdp = cmdlookup(name, 1);
@@ -520,8 +422,12 @@ loop:
/* We failed. If there was an entry for this command, delete it */
if (cmdp)
delete_cmd_entry();
if (printerr)
outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC));
if (printerr) {
if (e == ENOENT || e == ENOTDIR)
outfmt(out2, "%s: not found\n", name);
else
outfmt(out2, "%s: %s\n", name, strerror(e));
}
entry->cmdtype = CMDUNKNOWN;
return;
@@ -538,10 +444,9 @@ success:
*/
int
find_builtin(name)
char *name;
{
const register struct builtincmd *bp;
find_builtin(char *name)
{
const struct builtincmd *bp;
for (bp = builtincmd ; bp->name ; bp++) {
if (*bp->name == *name && equal(bp->name, name))
@@ -558,14 +463,15 @@ find_builtin(name)
*/
void
hashcd() {
hashcd(void)
{
struct tblentry **pp;
struct tblentry *cmdp;
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) {
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) {
if (cmdp->cmdtype == CMDNORMAL
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))
cmdp->rehash = 1;
}
}
@@ -580,10 +486,9 @@ hashcd() {
*/
void
changepath(newval)
char *newval;
{
char *old, *new;
changepath(const char *newval)
{
const char *old, *new;
int index;
int firstchange;
int bltin;
@@ -596,8 +501,8 @@ changepath(newval)
for (;;) {
if (*old != *new) {
firstchange = index;
if (*old == '\0' && *new == ':'
|| *old == ':' && *new == '\0')
if ((*old == '\0' && *new == ':')
|| (*old == ':' && *new == '\0'))
firstchange++;
old = new; /* ignore subsequent differences */
}
@@ -624,8 +529,9 @@ changepath(newval)
* PATH which has changed.
*/
STATIC void
clearcmdentry(firstchange) {
void
clearcmdentry(int firstchange)
{
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
@@ -634,8 +540,10 @@ clearcmdentry(firstchange) {
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) {
pp = tblp;
while ((cmdp = *pp) != NULL) {
if (cmdp->cmdtype == CMDNORMAL && cmdp->param.index >= firstchange
|| cmdp->cmdtype == CMDBUILTIN && builtinloc >= firstchange) {
if ((cmdp->cmdtype == CMDNORMAL &&
cmdp->param.index >= firstchange)
|| (cmdp->cmdtype == CMDBUILTIN &&
builtinloc >= firstchange)) {
*pp = cmdp->next;
ckfree(cmdp);
} else {
@@ -652,15 +560,15 @@ clearcmdentry(firstchange) {
*/
#ifdef mkinit
MKINIT void deletefuncs();
INCLUDE "exec.h"
SHELLPROC {
deletefuncs();
}
#endif
void
deletefuncs() {
deletefuncs(void)
{
struct tblentry **tblp;
struct tblentry **pp;
struct tblentry *cmdp;
@@ -691,15 +599,14 @@ deletefuncs() {
* entry.
*/
struct tblentry **lastcmdentry;
STATIC struct tblentry **lastcmdentry;
STATIC struct tblentry *
cmdlookup(name, add)
char *name;
{
cmdlookup(char *name, int add)
{
int hashval;
register char *p;
char *p;
struct tblentry *cmdp;
struct tblentry **pp;
@@ -728,13 +635,13 @@ cmdlookup(name, add)
return cmdp;
}
/*
* Delete the command entry returned on the last lookup.
*/
STATIC void
delete_cmd_entry() {
delete_cmd_entry(void)
{
struct tblentry *cmdp;
INTOFF;
@@ -746,35 +653,14 @@ delete_cmd_entry() {
#ifdef notdef
void
getcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
struct tblentry *cmdp = cmdlookup(name, 0);
if (cmdp) {
entry->u = cmdp->param;
entry->cmdtype = cmdp->cmdtype;
} else {
entry->cmdtype = CMDUNKNOWN;
entry->u.index = 0;
}
}
#endif
/*
* Add a new command entry, replacing any existing command entry for
* the same name.
*/
void
addcmdentry(name, entry)
char *name;
struct cmdentry *entry;
{
static void
addcmdentry(char *name, struct cmdentry *entry)
{
struct tblentry *cmdp;
INTOFF;
@@ -793,10 +679,8 @@ addcmdentry(name, entry)
*/
void
defun(name, func)
char *name;
union node *func;
{
defun(char *name, union node *func)
{
struct cmdentry entry;
INTOFF;
@@ -811,14 +695,98 @@ defun(name, func)
* Delete a function if it exists.
*/
void
unsetfunc(name)
char *name;
{
int
unsetfunc(char *name)
{
struct tblentry *cmdp;
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) {
freefunc(cmdp->param.func);
delete_cmd_entry();
return (0);
}
return (0);
}
/*
* Locate and print what a word is...
*/
int
typecmd(int argc, char **argv)
{
struct cmdentry entry;
struct tblentry *cmdp;
char **pp;
struct alias *ap;
int i;
int error = 0;
extern char *const parsekwd[];
for (i = 1; i < argc; i++) {
out1str(argv[i]);
/* First look at the keywords */
for (pp = (char **)parsekwd; *pp; pp++)
if (**pp == *argv[i] && equal(*pp, argv[i]))
break;
if (*pp) {
out1str(" is a shell keyword\n");
continue;
}
/* Then look at the aliases */
if ((ap = lookupalias(argv[i], 1)) != NULL) {
out1fmt(" is an alias for %s\n", ap->val);
continue;
}
/* Then check if it is a tracked alias */
if ((cmdp = cmdlookup(argv[i], 0)) != NULL) {
entry.cmdtype = cmdp->cmdtype;
entry.u = cmdp->param;
}
else {
/* Finally use brute force */
find_command(argv[i], &entry, 0, pathval());
}
switch (entry.cmdtype) {
case CMDNORMAL: {
if (strchr(argv[i], '/') == NULL) {
char *path = pathval(), *name;
int j = entry.u.index;
do {
name = padvance(&path, argv[i]);
stunalloc(name);
} while (--j >= 0);
out1fmt(" is%s %s\n",
cmdp ? " a tracked alias for" : "", name);
} else {
if (access(argv[i], X_OK) == 0)
out1fmt(" is %s\n", argv[i]);
else
out1fmt(": %s\n", strerror(errno));
}
break;
}
case CMDFUNCTION:
out1str(" is a shell function\n");
break;
case CMDBUILTIN:
out1str(" is a shell builtin\n");
break;
default:
out1str(": not found\n");
error |= 127;
break;
}
}
return error;
}
/*
* $PchId: exec.c,v 1.6 2006/04/10 14:47:03 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)exec.h 5.1 (Berkeley) 3/7/91
* @(#)exec.h 8.3 (Berkeley) 6/8/95
* $FreeBSD: src/bin/sh/exec.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
/* values of cmdtype */
@@ -53,23 +50,21 @@ struct cmdentry {
extern char *pathopt; /* set by padvance */
extern int exerrno; /* last exec error */
#ifdef __STDC__
void shellexec(char **, char **, char *, int);
char *padvance(char **, char *);
void find_command(char *, struct cmdentry *, int);
int hashcmd(int, char **);
void find_command(char *, struct cmdentry *, int, char *);
int find_builtin(char *);
void hashcd(void);
void changepath(char *);
void changepath(const char *);
void deletefuncs(void);
void defun(char *, union node *);
void unsetfunc(char *);
#else
void shellexec();
char *padvance();
void find_command();
int find_builtin();
void hashcd();
void changepath();
void defun();
void unsetfunc();
#endif
int unsetfunc(char *);
int typecmd(int, char **);
void clearcmdentry(int);
/*
* $PchId: exec.h,v 1.5 2006/04/10 14:47:34 philip Exp $
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)expand.h 5.1 (Berkeley) 3/7/91
* @(#)expand.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/expand.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
struct strlist {
@@ -47,17 +44,24 @@ struct arglist {
struct strlist **lastp;
};
#ifdef __STDC__
/*
* expandarg() flags
*/
#define EXP_FULL 0x1 /* perform word splitting & file globbing */
#define EXP_TILDE 0x2 /* do normal tilde expansion */
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */
union node;
void expandarg(union node *, struct arglist *, int);
void expandhere(union node *, int);
int patmatch(char *, char *);
void expandarg(union node *, struct arglist *, int);
int patmatch(char *, char *, int);
void rmescapes(char *);
int casematch(union node *, char *);
#else
void expandarg();
void expandhere();
int patmatch();
void rmescapes();
int casematch();
#endif
int wordexpcmd(int, char **);
/*
* $PchId: expand.h,v 1.4 2006/03/30 14:50:52 philip Exp $
*/

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)cmv 5.1 (Berkeley) 3/7/91
# @(#)cmv 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/cmv,v 1.7 2004/04/06 20:06:53 markm Exp $
# Conditional move--don't replace an existing file.
@@ -47,3 +44,6 @@ cmv() {
fi
/bin/mv "$1" "$2"
}
#
# $PchId: cmv,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)dirs 5.1 (Berkeley) 3/7/91
# @(#)dirs 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/dirs,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: dirs,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)kill 5.1 (Berkeley) 3/7/91
# @(#)kill 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/kill,v 1.7 2004/04/06 20:06:53 markm Exp $
# Convert job names to process ids and then run /bin/kill.
@@ -47,3 +44,6 @@ kill() {
done
/bin/kill $args
}
#
# $PchId: kill,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,11 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)login 5.1 (Berkeley) 3/7/91
# @(#)login 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/login,v 1.7 2004/04/06 20:06:53 markm Exp $
# replaces the login builtin in the BSD shell
login () exec login "$@"
#
# $PchId: login,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,6 +28,10 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)newgrp 5.1 (Berkeley) 3/7/91
# @(#)newgrp 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/newgrp,v 1.7 2004/04/06 20:06:53 markm Exp $
newgrp() exec newgrp "$@"
#
# $PchId: newgrp,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)popd 5.1 (Berkeley) 3/7/91
# @(#)popd 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/popd,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: popd,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,7 +28,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)pushd 5.1 (Berkeley) 3/7/91
# @(#)pushd 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/pushd,v 1.7 2004/04/06 20:06:53 markm Exp $
# pushd, popd, and dirs --- written by Chris Bertin
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris
@@ -71,3 +68,6 @@ dirs () {
echo "`pwd` $DSTACK"
return 0
}
#
# $PchId: pushd,v 1.2 2006/03/29 10:43:18 philip Exp $

View File

@@ -1,5 +1,5 @@
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -12,10 +12,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -32,10 +28,14 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)suspend 5.1 (Berkeley) 3/7/91
# @(#)suspend 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/funcs/suspend,v 1.7 2004/04/06 20:06:53 markm Exp $
suspend() {
local -
set +j
kill -TSTP 0
}
#
# $PchId: suspend,v 1.2 2006/03/29 10:43:18 philip Exp $

533
commands/ash/histedit.c Normal file
View File

@@ -0,0 +1,533 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/histedit.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <limits.h>
#ifndef NO_PATHS_H
#include <paths.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/*
* Editline and history functions (and glue).
*/
#include "shell.h"
#include "parser.h"
#include "var.h"
#include "options.h"
#include "main.h"
#include "output.h"
#include "mystring.h"
#include "builtins.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#include "complete.h"
#include "error.h"
#include "eval.h"
#include "memalloc.h"
#define MAXHISTLOOPS 4 /* max recursions through fc */
#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */
History *hist; /* history cookie */
EditLine *el; /* editline cookie */
int displayhist;
static FILE *el_in, *el_out, *el_err;
STATIC char *fc_replace(const char *, char *, char *);
STATIC int not_fcnumber(char *);
STATIC int str_to_event(char *, int);
/*
* Set history and editing status. Called whenever the status may
* have changed (figures out what to do).
*/
void
histedit(void)
{
#define editing (Eflag || Vflag)
if (iflag) {
if (!hist) {
/*
* turn history on
*/
INTOFF;
hist = history_init();
INTON;
if (hist != NULL)
sethistsize(histsizeval());
else
out2str("sh: can't initialize history\n");
}
if (editing && !el && isatty(0)) { /* && isatty(2) ??? */
/*
* turn editing on
*/
INTOFF;
if (el_in == NULL)
el_in = fdopen(0, "r");
if (el_err == NULL)
el_err = fdopen(1, "w");
if (el_out == NULL)
el_out = fdopen(2, "w");
if (el_in == NULL || el_err == NULL || el_out == NULL)
goto bad;
el = el_init(arg0, el_in, el_out, el_err);
if (el != NULL) {
if (hist)
el_set(el, EL_HIST, history, hist);
el_set(el, EL_PROMPT, getprompt);
} else {
bad:
out2str("sh: can't initialize editing\n");
}
INTON;
} else if (!editing && el) {
INTOFF;
el_end(el);
el = NULL;
INTON;
}
if (el) {
if (Vflag)
el_set(el, EL_EDITOR, "vi");
else if (Eflag)
el_set(el, EL_EDITOR, "emacs");
el_set(el, EL_ADDFN, "ed-do-complete",
"Complete Argument", complete);
el_set(el, EL_ADDFN, "ed-list-complete",
"List Argument Completions", complete_list);
el_set(el, EL_ADDFN, "ed-maybe-complete",
"Complete Argument Or List Completions",
complete_or_list);
el_set(el, EL_ADDFN, "ed-expand",
"Expand Completions", complete_expand);
el_set(el, EL_BIND, "^I", "ed-maybe-complete", NULL);
el_set(el, EL_BIND, "-a", "=", "ed-list-complete",
NULL);
el_set(el, EL_BIND, "-a", "\\\\", "ed-do-complete",
NULL);
el_set(el, EL_BIND, "-a", "*", "ed-expand",
NULL);
el_source(el, NULL);
}
} else {
INTOFF;
if (el) { /* no editing if not interactive */
el_end(el);
el = NULL;
}
if (hist) {
history_end(hist);
hist = NULL;
}
INTON;
}
}
void
sethistsize(hs)
const char *hs;
{
int histsize;
HistEvent he;
if (hist != NULL) {
if (hs == NULL || *hs == '\0' ||
(histsize = atoi(hs)) < 0)
histsize = 100;
history(hist, &he, H_EVENT, histsize);
}
}
int
histcmd(int argc, char **argv)
{
int ch;
char *editor = NULL;
HistEvent he;
int lflg = 0, nflg = 0, rflg = 0, sflg = 0;
int i, retval;
char *firststr, *laststr;
int first, last, direction;
char *pat = NULL, *repl;
static int active = 0;
struct jmploc jmploc;
struct jmploc *volatile savehandler;
char editfile[PATH_MAX];
FILE *efp;
int oldhistnum;
#ifdef __GNUC__
/* Avoid longjmp clobbering */
(void) &editor;
(void) &lflg;
(void) &nflg;
(void) &rflg;
(void) &sflg;
(void) &firststr;
(void) &laststr;
(void) &pat;
(void) &repl;
(void) &efp;
(void) &argc;
(void) &argv;
#endif
if (hist == NULL)
error("history not active");
if (argc == 1)
error("missing history argument");
optreset = 1; optind = 1; /* initialize getopt */
opterr = 0;
while (not_fcnumber(argv[optind]) &&
(ch = getopt(argc, argv, ":e:lnrs")) != -1)
switch ((char)ch) {
case 'e':
editor = optarg;
break;
case 'l':
lflg = 1;
break;
case 'n':
nflg = 1;
break;
case 'r':
rflg = 1;
break;
case 's':
sflg = 1;
break;
case ':':
error("option -%c expects argument", optopt);
case '?':
default:
error("unknown option: -%c", optopt);
}
argc -= optind, argv += optind;
/*
* If executing...
*/
if (lflg == 0 || editor || sflg) {
lflg = 0; /* ignore */
editfile[0] = '\0';
/*
* Catch interrupts to reset active counter and
* cleanup temp files.
*/
if (setjmp(jmploc.loc)) {
active = 0;
if (*editfile)
unlink(editfile);
handler = savehandler;
longjmp(handler->loc, 1);
}
savehandler = handler;
handler = &jmploc;
if (++active > MAXHISTLOOPS) {
active = 0;
displayhist = 0;
error("called recursively too many times");
}
/*
* Set editor.
*/
if (sflg == 0) {
if (editor == NULL &&
(editor = bltinlookup("FCEDIT", 1)) == NULL &&
(editor = bltinlookup("EDITOR", 1)) == NULL)
editor = DEFEDITOR;
if (editor[0] == '-' && editor[1] == '\0') {
sflg = 1; /* no edit */
editor = NULL;
}
}
}
/*
* If executing, parse [old=new] now
*/
if (lflg == 0 && argc > 0 &&
((repl = strchr(argv[0], '=')) != NULL)) {
pat = argv[0];
*repl++ = '\0';
argc--, argv++;
}
/*
* determine [first] and [last]
*/
switch (argc) {
case 0:
firststr = lflg ? "-16" : "-1";
laststr = "-1";
break;
case 1:
firststr = argv[0];
laststr = lflg ? "-1" : argv[0];
break;
case 2:
firststr = argv[0];
laststr = argv[1];
break;
default:
error("too many args");
}
/*
* Turn into event numbers.
*/
first = str_to_event(firststr, 0);
last = str_to_event(laststr, 1);
if (rflg) {
i = last;
last = first;
first = i;
}
/*
* XXX - this should not depend on the event numbers
* always increasing. Add sequence numbers or offset
* to the history element in next (diskbased) release.
*/
direction = first < last ? H_PREV : H_NEXT;
/*
* If editing, grab a temp file.
*/
if (editor) {
int fd;
INTOFF; /* easier */
sprintf(editfile, "%s/_shXXXXXX", _PATH_TMP);
if ((fd = mkstemp(editfile)) < 0)
error("can't create temporary file %s", editfile);
if ((efp = fdopen(fd, "w")) == NULL) {
close(fd);
error("can't allocate stdio buffer for temp");
}
}
/*
* Loop through selected history events. If listing or executing,
* do it now. Otherwise, put into temp file and call the editor
* after.
*
* The history interface needs rethinking, as the following
* convolutions will demonstrate.
*/
history(hist, &he, H_FIRST);
retval = history(hist, &he, H_NEXT_EVENT, first);
for (;retval != -1; retval = history(hist, &he, direction)) {
if (lflg) {
if (!nflg)
out1fmt("%5d ", he.num);
out1str(he.str);
} else {
char *s = pat ?
fc_replace(he.str, pat, repl) : (char *)he.str;
if (sflg) {
if (displayhist) {
out2str(s);
}
evalstring(s);
if (displayhist && hist) {
/*
* XXX what about recursive and
* relative histnums.
*/
oldhistnum = he.num;
history(hist, &he, H_ENTER, s);
/*
* XXX H_ENTER moves the internal
* cursor, set it back to the current
* entry.
*/
retval = history(hist, &he,
H_NEXT_EVENT, oldhistnum);
}
} else
fputs(s, efp);
}
/*
* At end? (if we were to loose last, we'd sure be
* messed up).
*/
if (he.num == last)
break;
}
if (editor) {
char *editcmd;
fclose(efp);
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2);
sprintf(editcmd, "%s %s", editor, editfile);
evalstring(editcmd); /* XXX - should use no JC command */
INTON;
readcmdfile(editfile); /* XXX - should read back - quick tst */
unlink(editfile);
}
if (lflg == 0 && active > 0)
--active;
if (displayhist)
displayhist = 0;
return 0;
}
STATIC char *
fc_replace(const char *s, char *p, char *r)
{
char *dest;
int plen = strlen(p);
STARTSTACKSTR(dest);
while (*s) {
if (*s == *p && strncmp(s, p, plen) == 0) {
while (*r)
STPUTC(*r++, dest);
s += plen;
*p = '\0'; /* so no more matches */
} else
STPUTC(*s++, dest);
}
STACKSTRNUL(dest);
dest = grabstackstr(dest);
return (dest);
}
STATIC int
not_fcnumber(char *s)
{
if (s == NULL)
return (0);
if (*s == '-')
s++;
return (!is_number(s));
}
STATIC int
str_to_event(char *str, int last)
{
HistEvent he;
char *s = str;
int relative = 0;
int i, retval;
retval = history(hist, &he, H_FIRST);
switch (*s) {
case '-':
relative = 1;
/*FALLTHROUGH*/
case '+':
s++;
}
if (is_number(s)) {
i = atoi(s);
if (relative) {
while (retval != -1 && i--) {
retval = history(hist, &he, H_NEXT);
}
if (retval == -1)
retval = history(hist, &he, H_LAST);
} else {
retval = history(hist, &he, H_NEXT_EVENT, i);
if (retval == -1) {
/*
* the notion of first and last is
* backwards to that of the history package
*/
retval = history(hist, &he, last ? H_FIRST : H_LAST);
}
}
if (retval == -1)
error("history number %s not found (internal error)",
str);
} else {
/*
* pattern
*/
retval = history(hist, &he, H_PREV_STR, str);
if (retval == -1)
error("history pattern not found: %s", str);
}
return (he.num);
}
int
bindcmd(int argc, char **argv)
{
if (el == NULL)
error("line editing is disabled");
return (el_parse(el, argc, argv));
}
#else
#include "error.h"
int
histcmd(int argc, char **argv)
{
error("not compiled with history support");
/*NOTREACHED*/
return (0);
}
int
bindcmd(int argc, char **argv)
{
error("not compiled with line editing support");
return (0);
}
#endif /* !NO_HISTORY && !EDITLINE */
/*
* $PchId: histedit.c,v 1.6 2006/04/10 14:52:58 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,15 +29,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)init.h 5.1 (Berkeley) 3/7/91
* @(#)init.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/init.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifdef __STDC__
void init(void);
void reset(void);
void initshellproc(void);
#else
void init();
void reset();
void initshellproc();
#endif
/*
* $PchId: init.h,v 1.3 2006/03/30 14:31:06 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,26 +31,62 @@
*/
#ifndef lint
static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 7/1/91";
#if 0
static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/input.c,v 1.22 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <stdio.h> /* defines BUFSIZ */
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
/*
* This file implements the input routines used by the parser.
*/
#include <sys/types.h>
#include <stdio.h> /* defines BUFSIZ */
#include "shell.h"
#include <fcntl.h>
#include <errno.h>
#include "redir.h"
#include "syntax.h"
#include "input.h"
#include "output.h"
#include "options.h"
#include "memalloc.h"
#include "error.h"
#include "alias.h"
#include "parser.h"
#ifdef EDITLINE
#ifdef __minix_vmd
#include <readline/readline.h>
#else
/* What about other systems? */
char *readline(char *prompt);
#endif
#else
#include "myhistedit.h"
#endif
#include "redir.h"
#include "trap.h"
static void popstring(void);
#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */
MKINIT
struct strpush {
struct strpush *prev; /* preceding string on stack */
char *prevstring;
int prevnleft;
int prevlleft;
struct alias *ap; /* if push was associated with an alias */
};
/*
* The parsefile structure pointed to by the global variable parsefile
@@ -63,36 +95,34 @@ static char sccsid[] = "@(#)input.c 5.4 (Berkeley) 7/1/91";
MKINIT
struct parsefile {
struct parsefile *prev; /* preceding file on stack */
int linno; /* current line */
int fd; /* file descriptor (or -1 if string) */
int nleft; /* number of chars left in buffer */
int nleft; /* number of chars left in this line */
int lleft; /* number of lines left in this buffer */
char *nextc; /* next char in buffer */
struct parsefile *prev; /* preceding file on stack */
char *buf; /* input buffer */
struct strpush *strpush; /* for pushing strings at this level */
struct strpush basestrpush; /* so pushing one is fast */
};
int plinno = 1; /* input line number */
MKINIT int parsenleft; /* copy of parsefile->nleft */
MKINIT int parselleft; /* copy of parsefile->lleft */
char *parsenextc; /* copy of parsefile->nextc */
MKINIT struct parsefile basepf; /* top level input file */
char basebuf[BUFSIZ]; /* buffer for top level input file */
struct parsefile *parsefile = &basepf; /* current input file */
char *pushedstring; /* copy of parsenextc when text pushed back */
int pushednleft; /* copy of parsenleft when text pushed back */
STATIC struct parsefile *parsefile = &basepf; /* current input file */
int init_editline = 0; /* editline library initialized? */
int whichprompt; /* -1 == PSE, 1 == PS1, 2 == PS2 */
#if READLINE
char *readline __P((const char *prompt));
char *r_use_prompt = NULL; /* the prompt to use with readline */
#ifndef EDITLINE
EditLine *el; /* cookie for editline package */
#endif
#ifdef __STDC__
STATIC void pushfile(void);
#else
STATIC void pushfile();
#endif
static int preadfd(void);
#ifdef mkinit
INCLUDE "input.h"
@@ -106,7 +136,7 @@ INIT {
RESET {
if (exception != EXSHELLPROC)
parsenleft = 0; /* clear input buffer */
parselleft = parsenleft = 0; /* clear input buffer */
popallfiles();
}
@@ -121,10 +151,9 @@ SHELLPROC {
*/
char *
pfgets(line, len)
char *line;
{
register char *p = line;
pfgets(char *line, int len)
{
char *p = line;
int nleft = len;
int c;
@@ -151,64 +180,74 @@ pfgets(line, len)
*/
int
pgetc() {
pgetc(void)
{
return pgetc_macro();
}
/*
* Refill the input buffer and return the next input character:
*
* 1) If a string was pushed back on the input, switch back to the regular
* buffer.
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
* from a string so we can't refill the buffer, return EOF.
* 3) Call read to read in the characters.
* 4) Delete all nul characters from the buffer.
*/
static int
preadfd(void)
{
int nr;
parsenextc = parsefile->buf;
int
preadbuffer() {
register char *p, *q;
register int i;
if (pushedstring) {
parsenextc = pushedstring;
pushedstring = NULL;
parsenleft = pushednleft;
if (--parsenleft >= 0)
return *parsenextc++;
#if !defined(NO_HISTORY) && !defined(EDITLINE)
if (el != NULL && gotwinch) {
gotwinch = 0;
el_resize(el);
}
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
return PEOF;
flushout(&output);
flushout(&errout);
#if READLINE
/* Use the readline() call if a prompt is to be printed (interactive). */
if (r_use_prompt != NULL) {
char *prompt;
char *line;
p = parsenextc = parsefile->buf;
prompt = r_use_prompt;
r_use_prompt = NULL;
if ((line = readline(prompt)) == NULL) {
parsenleft = EOF_NLEFT;
return PEOF;
}
strcpy(p, line);
free(line);
i = strlen(p);
p[i++] = '\n';
} else {
#endif
retry:
p = parsenextc = parsefile->buf;
i = read(parsefile->fd, p, BUFSIZ);
if (i <= 0) {
if (i < 0) {
#ifndef NO_HISTORY
#ifdef EDITLINE
if (parsefile->fd == 0 && editable) {
static const char *rl_cp= NULL;
static size_t rl_off= 0;
if (!rl_cp)
{
rl_cp = readline(getprompt(NULL));
if (rl_cp == NULL)
nr = 0;
}
if (rl_cp)
{
nr= strlen(rl_cp+rl_off);
if (nr >= BUFSIZ-1)
{
nr= BUFSIZ-1;
(void) memcpy(parsenextc, rl_cp+rl_off, nr);
rl_off += nr;
}
else
{
(void) memcpy(parsenextc, rl_cp+rl_off, nr);
parsenextc[nr++]= '\n';
free(rl_cp);
rl_cp= NULL;
rl_off= 0;
}
}
} else
#else /* !EDITLINE */
if (parsefile->fd == 0 && el) {
const char *rl_cp;
rl_cp = el_gets(el, &nr);
if (rl_cp == NULL)
nr = 0;
else {
/* XXX - BUFSIZE should redesign so not necessary */
(void) strcpy(parsenextc, rl_cp);
}
} else
#endif /* !EDITLINE */
#endif
nr = read(parsefile->fd, parsenextc, BUFSIZ - 1);
if (nr <= 0) {
if (nr < 0) {
if (errno == EINTR)
goto retry;
#ifdef EWOULDBLOCK
@@ -222,35 +261,106 @@ retry:
}
}
}
#endif
#endif /* EWOULDBLOCK */
}
parsenleft = EOF_NLEFT;
return PEOF;
nr = -1;
}
#if READLINE
}
#endif
parsenleft = i - 1;
/* delete nul characters */
for (;;) {
if (*p++ == '\0')
break;
if (--i <= 0)
return *parsenextc++; /* no nul characters */
}
q = p - 1;
while (--i > 0) {
if (*p != '\0')
*q++ = *p;
p++;
}
if (q == parsefile->buf)
goto retry; /* buffer contained nothing but nuls */
parsenleft = q - parsefile->buf - 1;
return *parsenextc++;
return nr;
}
/*
* Refill the input buffer and return the next input character:
*
* 1) If a string was pushed back on the input, pop it;
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading
* from a string so we can't refill the buffer, return EOF.
* 3) If there is more in this buffer, use it else call read to fill it.
* 4) Process input up to the next newline, deleting nul characters.
*/
int
preadbuffer(void)
{
char *p, *q;
int more;
int something;
char savec;
if (parsefile->strpush) {
popstring();
if (--parsenleft >= 0)
return (*parsenextc++);
}
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL)
return PEOF;
flushout(&output);
flushout(&errout);
again:
if (parselleft <= 0) {
if ((parselleft = preadfd()) == -1) {
parselleft = parsenleft = EOF_NLEFT;
return PEOF;
}
}
q = p = parsenextc;
/* delete nul characters */
something = 0;
for (more = 1; more;) {
switch (*p) {
case '\0':
p++; /* Skip nul */
goto check;
case '\t':
case ' ':
break;
case '\n':
parsenleft = q - parsenextc;
more = 0; /* Stop processing here */
break;
default:
something = 1;
break;
}
*q++ = *p++;
check:
if (--parselleft <= 0) {
parsenleft = q - parsenextc - 1;
if (parsenleft < 0)
goto again;
*q = '\0';
more = 0;
}
}
savec = *q;
*q = '\0';
#if !defined(NO_HISTORY) && !defined(EDITLINE)
if (parsefile->fd == 0 && hist && something) {
HistEvent he;
INTOFF;
history(hist, &he, whichprompt == 1 ? H_ENTER : H_ADD,
parsenextc);
INTON;
}
#endif
if (vflag) {
out2str(parsenextc);
flushout(out2);
}
*q = savec;
return *parsenextc++;
}
/*
* Undo the last call to pgetc. Only one character may be pushed back.
@@ -258,28 +368,57 @@ retry:
*/
void
pungetc() {
pungetc(void)
{
parsenleft++;
parsenextc--;
}
/*
* Push a string back onto the input. This code doesn't work if the user
* tries to push back more than one string at once.
* Push a string back onto the input at this current parsefile level.
* We handle aliases this way.
*/
void
ppushback(string, length)
char *string;
{
pushedstring = parsenextc;
pushednleft = parsenleft;
parsenextc = string;
parsenleft = length;
pushstring(char *s, int len, void *ap)
{
struct strpush *sp;
INTOFF;
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/
if (parsefile->strpush) {
sp = ckmalloc(sizeof (struct strpush));
sp->prev = parsefile->strpush;
parsefile->strpush = sp;
} else
sp = parsefile->strpush = &(parsefile->basestrpush);
sp->prevstring = parsenextc;
sp->prevnleft = parsenleft;
sp->prevlleft = parselleft;
sp->ap = (struct alias *)ap;
if (ap)
((struct alias *)ap)->flag |= ALIASINUSE;
parsenextc = s;
parsenleft = len;
INTON;
}
static void
popstring(void)
{
struct strpush *sp = parsefile->strpush;
INTOFF;
parsenextc = sp->prevstring;
parsenleft = sp->prevnleft;
parselleft = sp->prevlleft;
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/
if (sp->ap)
sp->ap->flag &= ~ALIASINUSE;
parsefile->strpush = sp->prev;
if (sp != &(parsefile->basestrpush))
ckfree(sp);
INTON;
}
/*
* Set the input to take input from a file. If push is set, push the
@@ -287,17 +426,16 @@ ppushback(string, length)
*/
void
setinputfile(fname, push)
char *fname;
{
setinputfile(char *fname, int push)
{
int fd;
int fd2;
INTOFF;
if ((fd = open(fname, O_RDONLY)) < 0)
error("Can't open %s", fname);
error("Can't open %s: %s", fname, strerror(errno));
if (fd < 10) {
fd2 = copyfd(fd, 10);
fd2 = fcntl(fd, F_DUPFD, 10);
close(fd);
if (fd2 < 0)
error("Out of file descriptors");
@@ -314,8 +452,9 @@ setinputfile(fname, push)
*/
void
setinputfd(fd, push) {
(void) fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
setinputfd(int fd, int push)
{
(void)fcntl(fd, F_SETFD, FD_CLOEXEC);
if (push) {
pushfile();
parsefile->buf = ckmalloc(BUFSIZ);
@@ -325,7 +464,7 @@ setinputfd(fd, push) {
parsefile->fd = fd;
if (parsefile->buf == NULL)
parsefile->buf = ckmalloc(BUFSIZ);
parsenleft = 0;
parselleft = parsenleft = 0;
plinno = 1;
}
@@ -335,14 +474,13 @@ setinputfd(fd, push) {
*/
void
setinputstring(string, push)
char *string;
{
setinputstring(char *string, int push)
{
INTOFF;
if (push)
pushfile();
parsenextc = string;
parsenleft = strlen(string);
parselleft = parsenleft = strlen(string);
parsefile->buf = NULL;
plinno = 1;
INTON;
@@ -356,21 +494,26 @@ setinputstring(string, push)
*/
STATIC void
pushfile() {
pushfile(void)
{
struct parsefile *pf;
parsefile->nleft = parsenleft;
parsefile->lleft = parselleft;
parsefile->nextc = parsenextc;
parsefile->linno = plinno;
pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile));
pf->prev = parsefile;
pf->fd = -1;
pf->strpush = NULL;
pf->basestrpush.prev = NULL;
parsefile = pf;
}
void
popfile() {
popfile(void)
{
struct parsefile *pf = parsefile;
INTOFF;
@@ -378,9 +521,12 @@ popfile() {
close(pf->fd);
if (pf->buf)
ckfree(pf->buf);
while (pf->strpush)
popstring();
parsefile = pf->prev;
ckfree(pf);
parsenleft = parsefile->nleft;
parselleft = parsefile->lleft;
parsenextc = parsefile->nextc;
plinno = parsefile->linno;
INTON;
@@ -392,7 +538,8 @@ popfile() {
*/
void
popallfiles() {
popallfiles(void)
{
while (parsefile != &basepf)
popfile();
}
@@ -405,10 +552,15 @@ popallfiles() {
*/
void
closescript() {
closescript(void)
{
popallfiles();
if (parsefile->fd > 0) {
close(parsefile->fd);
parsefile->fd = 0;
}
}
/*
* $PchId: input.c,v 1.7 2006/05/29 13:09:38 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)input.h 5.1 (Berkeley) 3/7/91
* @(#)input.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/input.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
/* PEOF (the end of file marker) is defined in syntax.h */
@@ -46,39 +43,22 @@
extern int plinno;
extern int parsenleft; /* number of characters left in input buffer */
extern char *parsenextc; /* next character in input buffer */
extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */
#ifdef __STDC__
char *pfgets(char *, int);
int pgetc(void);
int preadbuffer(void);
void pungetc(void);
void ppushback(char *, int);
void pushstring(char *, int, void *);
void setinputfile(char *, int);
void setinputfd(int, int);
void setinputstring(char *, int);
void popfile(void);
void popallfiles(void);
void closescript(void);
#else
char *pfgets();
int pgetc();
int preadbuffer();
void pungetc();
void ppushback();
void setinputfile();
void setinputfd();
void setinputstring();
void popfile();
void popallfiles();
void closescript();
#endif
#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer())
#if READLINE
/* The variable "r_use_prompt" indicates the prompt to use with readline,
* *and* that readline may only be used if non-NULL.
/*
* $PchId: input.h,v 1.3 2006/03/30 13:49:37 philip Exp $
*/
extern char *r_use_prompt;
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)jobs.h 5.1 (Berkeley) 3/7/91
* @(#)jobs.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/jobs.h,v 1.18 2004/04/06 20:06:51 markm Exp $
*/
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */
@@ -41,6 +38,7 @@
#define FORK_BG 1
#define FORK_NOJOB 2
#include <signal.h> /* for sig_atomic_t */
/*
* A job structure contains information about a job. A job is either a
@@ -51,7 +49,7 @@
struct procstat {
pid_t pid; /* process id */
short status; /* status flags (defined above) */
int status; /* status flags (defined above) */
char *cmd; /* text of command being run */
};
@@ -64,33 +62,41 @@ struct procstat {
struct job {
struct procstat ps0; /* status of process */
struct procstat *ps; /* status or processes when more than one */
pid_t nprocs; /* number of processes */
short nprocs; /* number of processes */
pid_t pgrp; /* process group of this job */
char state; /* true if job is finished */
char used; /* true if this entry is in used */
char changed; /* true if status has changed */
char foreground; /* true if running in the foreground */
#if JOBS
char jobctl; /* job running under job control */
struct job *next; /* job used after this one */
#endif
};
extern pid_t backgndpid; /* pid of last background process */
extern int job_warning; /* user was warned about stopped jobs */
extern int in_waitcmd; /* are we in waitcmd()? */
extern int in_dowait; /* are we in dowait()? */
extern volatile sig_atomic_t breakwaitcmd; /* break wait to process traps? */
#ifdef __STDC__
void setjobctl(int);
void showjobs(int);
int fgcmd(int, char **);
int bgcmd(int, char **);
int jobscmd(int, char **);
void showjobs(int, int, int);
int waitcmd(int, char **);
int jobidcmd(int, char **);
struct job *makejob(union node *, int);
int forkshell(struct job *, union node *, int);
int waitforjob(struct job *);
#else
void setjobctl();
void showjobs();
struct job *makejob();
int forkshell();
int waitforjob();
#endif
pid_t forkshell(struct job *, union node *, int);
int waitforjob(struct job *, int *);
int stoppedjobs(void);
char *commandtext(union node *);
#if ! JOBS
#define setjobctl(on) /* do nothing */
#endif
/*
* $PchId: jobs.h,v 1.4 2006/03/30 12:07:24 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)machdep.h 5.1 (Berkeley) 3/7/91
* @(#)machdep.h 8.2 (Berkeley) 5/4/95
*/
/*
@@ -47,5 +47,9 @@ union align {
char *cp;
};
#define ALIGN(nbytes) ((nbytes) + sizeof(union align) - 1 &~ (sizeof(union align) - 1))
#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1))
#endif
/*
* $PchId: machdep.h,v 1.2 2001/05/15 16:36:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mail.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mail.c,v 1.13 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Routines to check for mail. (Perhaps make part of main.c?)
@@ -48,8 +50,10 @@ static char sccsid[] = "@(#)mail.c 5.1 (Berkeley) 3/7/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "mail.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#define MAXMBOXES 10
@@ -67,11 +71,12 @@ STATIC time_t mailtime[MAXMBOXES]; /* times of mailboxes */
*/
void
chkmail(silent) {
register int i;
chkmail(int silent)
{
int i;
char *mpath;
char *p;
register char *q;
char *q;
struct stackmark smark;
struct stat statb;
@@ -91,18 +96,28 @@ chkmail(silent) {
if (q[-1] != '/')
abort();
q[-1] = '\0'; /* delete trailing '/' */
#ifdef notdef /* this is what the System V shell claims to do (it lies) */
if (stat(p, &statb) < 0)
statb.st_mtime = 0;
if (!silent
&& statb.st_size > 0
&& statb.st_mtime > mailtime[i]
&& statb.st_mtime > statb.st_atime
) {
out2str(pathopt? pathopt : "You have mail");
if (statb.st_mtime > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_mtime;
#else /* this is what it should do */
if (stat(p, &statb) < 0)
statb.st_size = 0;
if (statb.st_size > mailtime[i] && ! silent) {
out2str(pathopt? pathopt : "you have mail");
out2c('\n');
}
mailtime[i] = statb.st_size;
#endif
}
nmboxes = i;
popstackmark(&smark);
}
/*
* $PchId: mail.c,v 1.5 2006/05/22 12:02:37 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,11 +29,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mail.h 5.1 (Berkeley) 3/7/91
* @(#)mail.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/mail.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifdef __STDC__
void chkmail(int);
#else
void chkmail();
#endif
/*
* $PchId: mail.h,v 1.3 2006/03/30 11:53:44 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,18 +31,29 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/28/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/main.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <stdio.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <locale.h>
#include <errno.h>
#include "shell.h"
#include "main.h"
#include "mail.h"
@@ -54,38 +61,26 @@ static char sccsid[] = "@(#)main.c 5.2 (Berkeley) 3/13/91";
#include "output.h"
#include "parser.h"
#include "nodes.h"
#include "expand.h"
#include "eval.h"
#include "jobs.h"
#include "input.h"
#include "trap.h"
#if ATTY
#include "var.h"
#endif
#include "show.h"
#include "memalloc.h"
#include "error.h"
#include "init.h"
#include "mystring.h"
#define PROFILE 0
#include "exec.h"
#include "cd.h"
#include "builtins.h"
int rootpid;
int rootshell;
STATIC union node *curcmd;
STATIC union node *prevcmd;
extern int errno;
#if PROFILE
short profile_buf[16384];
extern int etext();
#endif
#ifdef __STDC__
STATIC void read_profile(char *);
char *getenv(char *);
#else
STATIC void read_profile();
char *getenv();
#endif
STATIC char *find_dot_file(char *);
/*
* Main routine. We initialize things, parse the arguments, execute
@@ -95,16 +90,15 @@ char *getenv();
* is used to figure out how far we had gotten.
*/
main(argc, argv) char **argv; {
int
main(int argc, char *argv[])
{
struct jmploc jmploc;
struct stackmark smark;
volatile int state;
char *shinit, *home;
char *profile = NULL, *ashrc = NULL;
char *shinit;
#if PROFILE
monitor(4, etext, profile_buf, sizeof profile_buf, 50);
#endif
(void) setlocale(LC_ALL, "");
state = 0;
if (setjmp(jmploc.loc)) {
/*
@@ -112,20 +106,32 @@ main(argc, argv) char **argv; {
* exception EXSHELLPROC to clean up before executing
* the shell procedure.
*/
if (exception == EXSHELLPROC) {
switch (exception) {
case EXSHELLPROC:
rootpid = getpid();
rootshell = 1;
minusc = NULL;
state = 3;
} else if (state == 0 || iflag == 0 || ! rootshell)
exitshell(2);
break;
case EXEXEC:
exitstatus = exerrno;
break;
case EXERROR:
exitstatus = 2;
break;
default:
break;
}
if (exception != EXSHELLPROC) {
if (state == 0 || iflag == 0 || ! rootshell)
exitshell(exitstatus);
}
reset();
#if ATTY
if (exception == EXINT
&& (! attyset() || equal(termval(), "emacs"))) {
#else
if (exception == EXINT) {
#endif
out2c('\n');
flushout(&errout);
}
@@ -150,57 +156,38 @@ main(argc, argv) char **argv; {
init();
setstackmark(&smark);
procargs(argc, argv);
if (eflag) eflag = 2; /* Truly enable [ex]flag after init. */
if (xflag) xflag = 2;
if (getpwd() == NULL && iflag)
out2str("sh: cannot determine working directory\n");
if (argv[0] && argv[0][0] == '-') {
state = 1;
read_profile("/etc/profile");
state1:
state = 2;
if ((home = getenv("HOME")) != NULL
&& (profile = (char *) malloc(strlen(home) + 10)) != NULL)
{
strcpy(profile, home);
strcat(profile, "/.profile");
read_profile(profile);
} else {
if (privileged == 0)
read_profile(".profile");
}
} else if ((sflag || minusc) && (shinit = getenv("SHINIT")) != NULL) {
state = 2;
evalstring(shinit);
else
read_profile("/etc/suid_profile");
}
state2:
if (profile != NULL) free(profile);
state = 3;
if (!argv[0] || argv[0][0] != '-') {
if ((home = getenv("HOME")) != NULL
&& (ashrc = (char *) malloc(strlen(home) + 8)) != NULL)
{
strcpy(ashrc, home);
strcat(ashrc, "/.ashrc");
read_profile(ashrc);
if (!privileged && iflag) {
if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') {
state = 3;
read_profile(shinit);
}
}
state3:
if (ashrc != NULL) free(ashrc);
if (eflag) eflag = 1; /* Init done, enable [ex]flag */
if (xflag) xflag = 1;
exitstatus = 0; /* Init shouldn't influence initial $? */
state = 4;
if (minusc) {
evalstring(minusc);
}
if (sflag || minusc == NULL) {
state4:
state4: /* XXX ??? - why isn't this before the "if" statement */
cmdloop(1);
}
#if PROFILE
monitor(0);
#endif
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
@@ -210,52 +197,49 @@ state4:
*/
void
cmdloop(top) {
cmdloop(int top)
{
union node *n;
struct stackmark smark;
int inter;
int numeof;
int numeof = 0;
TRACE(("cmdloop(%d) called\n", top));
setstackmark(&smark);
numeof = 0;
for (;;) {
if (pendingsigs)
dotrap();
inter = 0;
if (iflag && top) {
inter++;
showjobs(1);
showjobs(1, 0, 0);
chkmail(0);
flushout(&output);
}
n = parsecmd(inter);
#if DEBUG
/* showtree(n); */
#endif
/* showtree(n); DEBUG */
if (n == NEOF) {
if (Iflag == 0 || numeof >= 50)
if (!top || numeof >= 50)
break;
out2str("\nUse \"exit\" to leave shell.\n");
if (!stoppedjobs()) {
if (!Iflag)
break;
out2str("\nUse \"exit\" to leave shell.\n");
}
numeof++;
} else if (n != NULL && nflag == 0) {
if (inter) {
INTOFF;
if (prevcmd)
freefunc(prevcmd);
prevcmd = curcmd;
curcmd = copyfunc(n);
INTON;
}
job_warning = (job_warning == 2) ? 1 : 0;
numeof = 0;
evaltree(n, 0);
#ifdef notdef
if (exitstatus) /*DEBUG*/
outfmt(&errout, "Exit status 0x%X\n", exitstatus);
#endif
}
popstackmark(&smark);
setstackmark(&smark);
if (evalskip == SKIPFILE) {
evalskip = 0;
break;
}
}
popstackmark(&smark); /* unnecessary */
popstackmark(&smark);
}
@@ -265,9 +249,8 @@ cmdloop(top) {
*/
STATIC void
read_profile(name)
char *name;
{
read_profile(char *name)
{
int fd;
INTOFF;
@@ -287,32 +270,63 @@ read_profile(name)
*/
void
readcmdfile(name)
char *name;
{
readcmdfile(char *name)
{
int fd;
INTOFF;
if ((fd = open(name, O_RDONLY)) >= 0)
setinputfd(fd, 1);
else
error("Can't open %s", name);
error("Can't open %s: %s", name, strerror(errno));
INTON;
cmdloop(0);
popfile();
}
/*
* Take commands from a file. To be compatable we should do a path
* search for the file, but a path search doesn't make any sense.
* Take commands from a file. To be compatible we should do a path
* search for the file, which is necessary to find sub-commands.
*/
dotcmd(argc, argv) char **argv; {
STATIC char *
find_dot_file(char *basename)
{
static char localname[FILENAME_MAX+1];
char *fullname;
char *path = pathval();
struct stat statb;
/* don't try this for absolute or relative paths */
if( strchr(basename, '/'))
return basename;
while ((fullname = padvance(&path, basename)) != NULL) {
strcpy(localname, fullname);
stunalloc(fullname);
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode))
return localname;
}
return basename;
}
int
dotcmd(int argc, char **argv)
{
struct strlist *sp;
exitstatus = 0;
for (sp = cmdenviron; sp ; sp = sp->next)
setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED);
if (argc >= 2) { /* That's what SVR2 does */
setinputfile(argv[1], 1);
commandname = argv[1];
char *fullname = find_dot_file(argv[1]);
setinputfile(fullname, 1);
commandname = fullname;
cmdloop(0);
popfile();
}
@@ -320,40 +334,22 @@ dotcmd(argc, argv) char **argv; {
}
exitcmd(argc, argv) char **argv; {
int
exitcmd(int argc, char **argv)
{
extern int oexitstatus;
if (stoppedjobs())
return 0;
if (argc > 1)
exitstatus = number(argv[1]);
else
exitstatus = oexitstatus;
exitshell(exitstatus);
/*NOTREACHED*/
return 0;
}
lccmd(argc, argv) char **argv; {
if (argc > 1) {
defun(argv[1], prevcmd);
return 0;
} else {
INTOFF;
freefunc(curcmd);
curcmd = prevcmd;
prevcmd = NULL;
INTON;
evaltree(curcmd, 0);
return exitstatus;
}
}
#ifdef notdef
/*
* Should never be called.
* $PchId: main.c,v 1.5 2006/05/22 12:03:02 philip Exp $
*/
void
exit(exitstatus) {
_exit(exitstatus);
}
#endif

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,16 +29,18 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)main.h 5.1 (Berkeley) 3/7/91
* @(#)main.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/main.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
extern int rootpid; /* pid of main shell */
extern int rootshell; /* true if we aren't a child of the main shell */
#ifdef __STDC__
void readcmdfile(char *);
void cmdloop(int);
#else
void readcmdfile();
void cmdloop();
#endif
int dotcmd(int, char **);
int exitcmd(int, char **);
/*
* $PchId: main.h,v 1.3 2006/03/30 11:43:59 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,24 +31,33 @@
*/
#ifndef lint
static char sccsid[] = "@(#)memalloc.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/memalloc.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include "shell.h"
#include "output.h"
#include "machdep.h"
#include "memalloc.h"
#include "error.h"
#include "machdep.h"
#include "mystring.h"
#include "expand.h"
#include <stdlib.h>
#include <unistd.h>
/*
* Like malloc, but returns an error when out of space.
*/
pointer
ckmalloc(nbytes) {
register pointer p;
pointer malloc();
ckmalloc(int nbytes)
{
pointer p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
@@ -65,11 +70,8 @@ ckmalloc(nbytes) {
*/
pointer
ckrealloc(p, nbytes)
register pointer p;
{
pointer realloc();
ckrealloc(pointer p, int nbytes)
{
if ((p = realloc(p, nbytes)) == NULL)
error("Out of space");
return p;
@@ -81,10 +83,9 @@ ckrealloc(p, nbytes)
*/
char *
savestr(s)
char *s;
{
register char *p;
savestr(char *s)
{
char *p;
p = ckmalloc(strlen(s) + 1);
scopy(s, p);
@@ -97,47 +98,56 @@ savestr(s)
* to make this more efficient, and also to avoid all sorts of exception
* handling code to handle interrupts in the middle of a parse.
*
* The size 504 was chosen because the Ultrix malloc handles that size
* well.
* The size 496 was chosen because with 16-byte alignment the total size
* for the allocated block is 512.
*/
#define MINSIZE 504 /* minimum size of a block */
#define MINSIZE 496 /* minimum size of a block. */
struct stack_block {
struct stack_block *prev;
char space[MINSIZE];
/* Data follows */
};
#define SPACE(sp) ((char*)(sp) + ALIGN(sizeof(struct stack_block)))
struct stack_block stackbase;
struct stack_block *stackp = &stackbase;
char *stacknxt = stackbase.space;
int stacknleft = MINSIZE;
STATIC struct stack_block *stackp;
STATIC struct stackmark *markp;
char *stacknxt;
int stacknleft;
int sstrnleft;
int herefd = -1;
static void
stnewblock(int nbytes)
{
struct stack_block *sp;
int allocsize;
if (nbytes < MINSIZE)
nbytes = MINSIZE;
allocsize = ALIGN(sizeof(struct stack_block)) + ALIGN(nbytes);
INTOFF;
sp = ckmalloc(allocsize);
sp->prev = stackp;
stacknxt = SPACE(sp);
stacknleft = allocsize - (stacknxt - (char*)sp);
stackp = sp;
INTON;
}
pointer
stalloc(nbytes) {
register char *p;
stalloc(int nbytes)
{
char *p;
nbytes = ALIGN(nbytes);
if (nbytes > stacknleft) {
int blocksize;
struct stack_block *sp;
blocksize = nbytes;
if (blocksize < MINSIZE)
blocksize = MINSIZE;
INTOFF;
sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize);
sp->prev = stackp;
stacknxt = sp->space;
stacknleft = blocksize;
stackp = sp;
INTON;
}
if (nbytes > stacknleft)
stnewblock(nbytes);
p = stacknxt;
stacknxt += nbytes;
stacknleft -= nbytes;
@@ -146,11 +156,10 @@ stalloc(nbytes) {
void
stunalloc(p)
pointer p;
{
stunalloc(pointer p)
{
if (p == NULL) { /*DEBUG */
write(2, "stunalloc\n", 10);
write(STDERR_FILENO, "stunalloc\n", 10);
abort();
}
stacknleft += stacknxt - (char *)p;
@@ -160,22 +169,23 @@ stunalloc(p)
void
setstackmark(mark)
struct stackmark *mark;
{
setstackmark(struct stackmark *mark)
{
mark->stackp = stackp;
mark->stacknxt = stacknxt;
mark->stacknleft = stacknleft;
mark->marknext = markp;
markp = mark;
}
void
popstackmark(mark)
struct stackmark *mark;
{
popstackmark(struct stackmark *mark)
{
struct stack_block *sp;
INTOFF;
markp = mark->marknext;
while (stackp != mark->stackp) {
sp = stackp;
stackp = sp->prev;
@@ -198,35 +208,56 @@ popstackmark(mark)
*/
void
growstackblock() {
growstackblock(void)
{
char *p;
int newlen = stacknleft * 2 + 100;
char *oldspace = stacknxt;
int oldlen = stacknleft;
int newlen;
char *oldspace;
int oldlen;
struct stack_block *sp;
struct stack_block *oldstackp;
struct stackmark *xmark;
if (stacknxt == stackp->space && stackp != &stackbase) {
newlen = (stacknleft == 0) ? MINSIZE : stacknleft * 2 + 100;
newlen = ALIGN(newlen);
oldspace = stacknxt;
oldlen = stacknleft;
if (stackp != NULL && stacknxt == SPACE(stackp)) {
INTOFF;
sp = stackp;
stackp = sp->prev;
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen);
oldstackp = stackp;
stackp = oldstackp->prev;
sp = ckrealloc((pointer)oldstackp, newlen);
sp->prev = stackp;
stackp = sp;
stacknxt = sp->space;
stacknleft = newlen;
stacknxt = SPACE(sp);
stacknleft = newlen - (stacknxt - (char*)sp);
/*
* Stack marks pointing to the start of the old block
* must be relocated to point to the new block
*/
xmark = markp;
while (xmark != NULL && xmark->stackp == oldstackp) {
xmark->stackp = stackp;
xmark->stacknxt = stacknxt;
xmark->stacknleft = stacknleft;
xmark = xmark->marknext;
}
INTON;
} else {
p = stalloc(newlen);
bcopy(oldspace, p, oldlen);
stacknxt = p; /* free the space */
stacknleft += newlen; /* we just allocated */
if (oldlen != 0)
memcpy(p, oldspace, oldlen);
stunalloc(p);
}
}
void
grabstackblock(len) {
grabstackblock(int len)
{
len = ALIGN(len);
stacknxt += len;
stacknleft -= len;
@@ -254,8 +285,11 @@ grabstackblock(len) {
char *
growstackstr() {
int len = stackblocksize();
growstackstr(void)
{
int len;
len = stackblocksize();
if (herefd >= 0 && len >= 1024) {
xwrite(herefd, stackblock(), len);
sstrnleft = len - 1;
@@ -272,8 +306,11 @@ growstackstr() {
*/
char *
makestrspace() {
int len = stackblocksize() - sstrnleft;
makestrspace(void)
{
int len;
len = stackblocksize() - sstrnleft;
growstackblock();
sstrnleft = stackblocksize() - len;
return stackblock() + len;
@@ -282,11 +319,13 @@ makestrspace() {
void
ungrabstackstr(s, p)
char *s;
char *p;
{
ungrabstackstr(char *s, char *p)
{
stacknleft += stacknxt - s;
stacknxt = s;
sstrnleft = stacknleft - (p - s);
}
/*
* $PchId: memalloc.c,v 1.5 2006/05/22 12:03:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,13 +29,15 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)memalloc.h 5.1 (Berkeley) 3/7/91
* @(#)memalloc.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/memalloc.h,v 1.9 2004/04/06 20:06:51 markm Exp $
*/
struct stackmark {
struct stack_block *stackp;
char *stacknxt;
int stacknleft;
struct stackmark *marknext;
};
@@ -48,10 +46,8 @@ extern int stacknleft;
extern int sstrnleft;
extern int herefd;
#ifdef __STDC__
pointer ckmalloc(int);
pointer ckrealloc(pointer, int);
void free(pointer); /* defined in C library */
char *savestr(char *);
pointer stalloc(int);
void stunalloc(pointer);
@@ -62,21 +58,6 @@ void grabstackblock(int);
char *growstackstr(void);
char *makestrspace(void);
void ungrabstackstr(char *, char *);
#else
pointer ckmalloc();
pointer ckrealloc();
void free(); /* defined in C library */
char *savestr();
pointer stalloc();
void stunalloc();
void setstackmark();
void popstackmark();
void growstackblock();
void grabstackblock();
char *growstackstr();
char *makestrspace();
void ungrabstackstr();
#endif
@@ -84,7 +65,7 @@ void ungrabstackstr();
#define stackblocksize() stacknleft
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize()
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c)))
#define CHECKSTRSPACE(n, p) if (sstrnleft < n) p = makestrspace(); else
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); }
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c))
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0'))
#define STUNPUTC(p) (++sstrnleft, --p)
@@ -93,3 +74,7 @@ void ungrabstackstr();
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft)
#define ckfree(p) free((pointer)(p))
/*
* $PchId: memalloc.h,v 1.3 2006/03/30 11:39:41 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,13 +31,32 @@
*/
#ifndef lint
static char sccsid[] = "@(#)miscbltin.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/miscbltin.c,v 1.30 2004/04/06 20:06:51 markm Exp $");
*/
/*
* Miscelaneous builtins.
* Miscellaneous builtins.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/select.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <termios.h>
#include "shell.h"
#include "options.h"
#include "var.h"
@@ -49,38 +64,71 @@ static char sccsid[] = "@(#)miscbltin.c 5.2 (Berkeley) 3/13/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "builtins.h"
#undef eflag
extern char **argptr; /* argument list for builtin command */
/*
* The read builtin. The -e option causes backslashes to escape the
* following character.
* The read builtin. The -r option causes backslashes to be treated like
* ordinary characters.
*
* This uses unbuffered input, which may be avoidable in some cases.
*/
readcmd(argc, argv) char **argv; {
int
readcmd(int argc __unused, char **argv __unused)
{
char **ap;
int backslash;
char c;
int eflag;
int rflag;
char *prompt;
char *ifs;
char *p;
int startword;
int status;
int i;
struct timeval tv;
char *tvptr;
#ifndef __minix_vmd
fd_set ifds;
#endif
struct termios told, tnew;
int tsaved;
eflag = 0;
rflag = 0;
prompt = NULL;
while ((i = nextopt("ep:")) != '\0') {
if (i == 'p')
prompt = optarg;
else
eflag = 1;
tv.tv_sec = -1;
tv.tv_usec = 0;
while ((i = nextopt("erp:t:")) != '\0') {
switch(i) {
case 'p':
prompt = shoptarg;
break;
case 'e':
break;
case 'r':
rflag = 1;
break;
case 't':
tv.tv_sec = strtol(shoptarg, &tvptr, 0);
if (tvptr == shoptarg)
error("timeout value");
switch(*tvptr) {
case 0:
case 's':
break;
case 'h':
tv.tv_sec *= 60;
/* FALLTHROUGH */
case 'm':
tv.tv_sec *= 60;
break;
default:
error("timeout unit");
}
break;
}
}
if (prompt && isatty(0)) {
out2str(prompt);
@@ -90,12 +138,45 @@ readcmd(argc, argv) char **argv; {
error("arg count");
if ((ifs = bltinlookup("IFS", 1)) == NULL)
ifs = nullstr;
if (tv.tv_sec >= 0) {
#ifdef __minix
abort();
#else
/*
* See if we can disable input processing; this will
* not give the desired result if we are in a pipeline
* and someone upstream is still in line-by-line mode.
*/
tsaved = 0;
if (tcgetattr(0, &told) == 0) {
memcpy(&tnew, &told, sizeof(told));
cfmakeraw(&tnew);
tcsetattr(0, TCSANOW, &tnew);
tsaved = 1;
}
/*
* Wait for something to become available.
*/
FD_ZERO(&ifds);
FD_SET(0, &ifds);
status = select(1, &ifds, NULL, NULL, &tv);
if (tsaved)
tcsetattr(0, TCSANOW, &told);
/*
* If there's nothing ready, return an error.
*/
if (status <= 0)
return(1);
#endif
}
status = 0;
startword = 1;
backslash = 0;
STARTSTACKSTR(p);
for (;;) {
if (read(0, &c, 1) != 1) {
if (read(STDIN_FILENO, &c, 1) != 1) {
status = 1;
break;
}
@@ -107,7 +188,7 @@ readcmd(argc, argv) char **argv; {
STPUTC(c, p);
continue;
}
if (eflag && c == '\\') {
if (!rflag && c == '\\') {
backslash++;
continue;
}
@@ -118,7 +199,7 @@ readcmd(argc, argv) char **argv; {
}
startword = 0;
if (backslash && c == '\\') {
if (read(0, &c, 1) != 1) {
if (read(STDIN_FILENO, &c, 1) != 1) {
status = 1;
break;
}
@@ -142,25 +223,274 @@ readcmd(argc, argv) char **argv; {
umaskcmd(argc, argv) char **argv; {
int
umaskcmd(int argc __unused, char **argv)
{
char *ap;
int mask;
char *p;
int i;
int symbolic_mode = 0;
if ((p = argv[1]) == NULL) {
INTOFF;
mask = umask(0);
umask(mask);
INTON;
out1fmt("%.4o\n", mask); /* %#o might be better */
while ((i = nextopt("S")) != '\0') {
symbolic_mode = 1;
}
INTOFF;
mask = umask(0);
umask(mask);
INTON;
if ((ap = *argptr) == NULL) {
if (symbolic_mode) {
char u[4], g[4], o[4];
i = 0;
if ((mask & S_IRUSR) == 0)
u[i++] = 'r';
if ((mask & S_IWUSR) == 0)
u[i++] = 'w';
if ((mask & S_IXUSR) == 0)
u[i++] = 'x';
u[i] = '\0';
i = 0;
if ((mask & S_IRGRP) == 0)
g[i++] = 'r';
if ((mask & S_IWGRP) == 0)
g[i++] = 'w';
if ((mask & S_IXGRP) == 0)
g[i++] = 'x';
g[i] = '\0';
i = 0;
if ((mask & S_IROTH) == 0)
o[i++] = 'r';
if ((mask & S_IWOTH) == 0)
o[i++] = 'w';
if ((mask & S_IXOTH) == 0)
o[i++] = 'x';
o[i] = '\0';
out1fmt("u=%s,g=%s,o=%s\n", u, g, o);
} else {
out1fmt("%.4o\n", mask);
}
} else {
mask = 0;
do {
if ((unsigned)(i = *p - '0') >= 8)
error("Illegal number: %s", argv[1]);
mask = (mask << 3) + i;
} while (*++p != '\0');
umask(mask);
if (isdigit(*ap)) {
mask = 0;
do {
if (*ap >= '8' || *ap < '0')
error("Illegal number: %s", argv[1]);
mask = (mask << 3) + (*ap - '0');
} while (*++ap != '\0');
umask(mask);
} else {
void *set;
if ((set = setmode (ap)) == 0)
error("Illegal number: %s", ap);
mask = getmode (set, ~mask & 0777);
umask(~mask & 0777);
free(set);
}
}
return 0;
}
#ifdef __minix
struct rlimit
{
unsigned long rlim_cur; /* current (soft) limit */
unsigned long rlim_max; /* maximum value for rlim_cur */
};
#define RLIM_INFINITY (((unsigned long)1 << 31) - 1)
int getrlimit (int, struct rlimit *);
int setrlimit (int, const struct rlimit *);
int getrlimit(resource, rlp)
int resource;
struct rlimit *rlp;
{
errno= ENOSYS;
return -1;
}
int setrlimit(resource, rlp)
int resource;
const struct rlimit *rlp;
{
errno= ENOSYS;
return -1;
}
#endif
/*
* ulimit builtin
*
* This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and
* Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with
* ash by J.T. Conklin.
*
* Public domain.
*/
struct limits {
const char *name;
const char *units;
int cmd;
int factor; /* multiply by to get rlim_{cur,max} values */
char option;
};
static const struct limits limits[] = {
#ifdef RLIMIT_CPU
{ "cpu time", "seconds", RLIMIT_CPU, 1, 't' },
#endif
#ifdef RLIMIT_FSIZE
{ "file size", "512-blocks", RLIMIT_FSIZE, 512, 'f' },
#endif
#ifdef RLIMIT_DATA
{ "data seg size", "kbytes", RLIMIT_DATA, 1024, 'd' },
#endif
#ifdef RLIMIT_STACK
{ "stack size", "kbytes", RLIMIT_STACK, 1024, 's' },
#endif
#ifdef RLIMIT_CORE
{ "core file size", "512-blocks", RLIMIT_CORE, 512, 'c' },
#endif
#ifdef RLIMIT_RSS
{ "max memory size", "kbytes", RLIMIT_RSS, 1024, 'm' },
#endif
#ifdef RLIMIT_MEMLOCK
{ "locked memory", "kbytes", RLIMIT_MEMLOCK, 1024, 'l' },
#endif
#ifdef RLIMIT_NPROC
{ "max user processes", (char *)0, RLIMIT_NPROC, 1, 'u' },
#endif
#ifdef RLIMIT_NOFILE
{ "open files", (char *)0, RLIMIT_NOFILE, 1, 'n' },
#endif
#ifdef RLIMIT_VMEM
{ "virtual mem size", "kbytes", RLIMIT_VMEM, 1024, 'v' },
#endif
#ifdef RLIMIT_SWAP
{ "swap limit", "kbytes", RLIMIT_SWAP, 1024, 'w' },
#endif
#ifdef RLIMIT_SBSIZE
{ "sbsize", "bytes", RLIMIT_SBSIZE, 1, 'b' },
#endif
{ (char *) 0, (char *)0, 0, 0, '\0' }
};
int
ulimitcmd(int argc __unused, char **argv __unused)
{
int c;
intmax_t val = 0;
enum { SOFT = 0x1, HARD = 0x2 }
how = SOFT | HARD;
const struct limits *l;
int set, all = 0;
int optc, what;
struct rlimit limit;
what = 'f';
while ((optc = nextopt("HSatfdsmcnuvlb")) != '\0')
switch (optc) {
case 'H':
how = HARD;
break;
case 'S':
how = SOFT;
break;
case 'a':
all = 1;
break;
default:
what = optc;
}
for (l = limits; l->name && l->option != what; l++)
;
if (!l->name)
error("internal error (%c)", what);
set = *argptr ? 1 : 0;
if (set) {
char *p = *argptr;
if (all || argptr[1])
error("too many arguments");
if (strcmp(p, "unlimited") == 0)
val = RLIM_INFINITY;
else {
val = 0;
while ((c = *p++) >= '0' && c <= '9')
{
val = (val * 10) + (long)(c - '0');
if (val < 0)
break;
}
if (c)
error("bad number");
val *= l->factor;
}
}
if (all) {
for (l = limits; l->name; l++) {
char optbuf[40];
if (getrlimit(l->cmd, &limit) < 0)
error("can't get limit: %s", strerror(errno));
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
if (l->units)
snprintf(optbuf, sizeof(optbuf),
"(%s, -%c) ", l->units, l->option);
else
snprintf(optbuf, sizeof(optbuf),
"(-%c) ", l->option);
out1fmt("%-18s %18s ", l->name, optbuf);
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
out1fmt("%jd\n", (intmax_t)val);
}
}
return 0;
}
if (getrlimit(l->cmd, &limit) < 0)
error("can't get limit: %s", strerror(errno));
if (set) {
if (how & SOFT)
limit.rlim_cur = val;
if (how & HARD)
limit.rlim_max = val;
if (setrlimit(l->cmd, &limit) < 0)
error("bad limit: %s", strerror(errno));
} else {
if (how & SOFT)
val = limit.rlim_cur;
else if (how & HARD)
val = limit.rlim_max;
if (val == RLIM_INFINITY)
out1fmt("unlimited\n");
else
{
val /= l->factor;
out1fmt("%jd\n", (intmax_t)val);
}
}
return 0;
}
/*
* $PchId: miscbltin.c,v 1.7 2006/05/23 11:59:08 philip Exp $
*/

View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +14,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,90 +30,69 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mkbuiltins 5.2 (Berkeley) 3/8/91
# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/mkbuiltins,v 1.13 2004/04/06 20:06:51 markm Exp $
# All calls to awk removed, because Minix bawk is deficient. (kjb)
if [ $# != 2 ]
then
echo "USAGE: $0 shell.h builtins"
exit 1
#temp=`/usr/bin/mktemp -t ka`
temp=/tmp/mkb$$
havehist=1
if [ "X$1" = "X-h" ]; then
havehist=0
shift
fi
SHL=$1
BLTINS=$2
temp=/tmp/ka$$
exec > builtins.c
havejobs=0
if [ "X$1" = "X-j" ]; then
havejobs=0
shift
elif grep '^#define[ ]*JOBS[ ]*1' $2 > /dev/null
then havejobs=1
fi
objdir=$1
exec > ${objdir}/builtins.c
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include <stdlib.h>
#include "shell.h"
#include "builtins.h"
!
if grep '^#define JOBS[ ]*1' $SHL > /dev/null
then
# Job control.
sed -e '/^#/d
s/ / /g
s/ #.*//
/^ *$/d
s/-j//' $BLTINS > $temp
else
# No job control.
sed -e '/^#/d
s/ / /g
s/ #.*//
/^ *$/d
/-j/d' $BLTINS > $temp
fi
sed -e 's/ .*//
s/\(.*\)/int \1();/' $temp
awk '/^[^#]/ {if(('$havejobs' || $2 != "-j") && ('$havehist' || $2 != "-h")) \
print $0}' $3 | sed 's/-[hj]//' > $temp
#awk '{ printf "int %s();\n", $1}' $temp
echo '
int (*const builtinfunc[])() = {'
sed -e 's/ .*//
s/\(.*\)/ \1,/' $temp
int (*const builtinfunc[]) (int, char **) = {'
awk '/^[^#]/ { printf "\t%s,\n", $1}' $temp
echo '};
const struct builtincmd builtincmd[] = {'
i=0
while read line
do
set -$- $line
shift
for fun
do
echo " \"$fun\", $i,"
done
i=`expr $i + 1`
done < $temp
echo ' NULL, 0
awk '{ for (i = 2 ; i <= NF ; i++) {
printf "\t{ \"%s\", %d },\n", $i, NR-1
}}' $temp
echo ' { NULL, 0 }
};'
exec > builtins.h
exec > ${objdir}/builtins.h
cat <<\!
/*
* This file was generated by the mkbuiltins program.
*/
#include <sys/cdefs.h>
!
i=0
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ < $temp |
while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done
awk '{ printf "#define %s %d\n", $1, NR-1}'
echo '
struct builtincmd {
char *name;
int code;
};
extern int (*const builtinfunc[])();
extern int (*const builtinfunc[]) (int, char **);
extern const struct builtincmd builtincmd[];'
awk '{ printf "int %s (int, char **);\n", $1 }' < $temp
rm -f $temp
#
# $PchId: mkbuiltins,v 1.6 2006/05/22 12:42:58 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,43 +31,51 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mkinit.c 5.3 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)mkinit.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mkinit.c,v 1.17 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program scans all the source files for code to handle various
* special events and combines this code into one file. This (allegedly)
* improves the structure of the program since there is no need for
* anyone outside of a module to know that that module performs special
* operations on particular events. The command is executed iff init.c
* is actually changed.
* operations on particular events.
*
* Usage: mkinit command sourcefile...
* Usage: mkinit sourcefile...
*/
#include <sys/cdefs.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#ifdef __minix
#define __unused
#endif
/*
* OUTFILE is the name of the output file. Output is initially written
* to the file OUTTEMP, which is then moved to OUTFILE if OUTTEMP and
* OUTFILE are different.
* to the file OUTTEMP, which is then moved to OUTFILE.
*/
#define OUTFILE "init.c"
#define OUTTEMP "init.c.new"
#define OUTOBJ "init.o"
/*
@@ -89,7 +93,7 @@ struct text {
int nleft;
struct block *start;
struct block *last;
};
};
struct block {
struct block *next;
@@ -105,7 +109,7 @@ struct event {
char *name; /* name of event (e.g. INIT) */
char *routine; /* name of routine called on event */
char *comment; /* comment describing routine */
struct text code; /* code for handling event */
struct text code; /* code for handling event */
};
@@ -148,42 +152,35 @@ struct text decls; /* declarations */
int amiddecls; /* for formatting */
void readfile(), doevent(), doinclude(), dodecl(), output();
void addstr(), addchar(), writetext();
static void readfile(char *);
static int match(char *, char *);
static int gooddefine(char *);
static void doevent(struct event *, FILE *, char *);
static void doinclude(char *);
static void dodecl(char *, FILE *);
static void output(void);
static void addstr(char *, struct text *);
static void addchar(int, struct text *);
static void writetext(struct text *, FILE *);
static FILE *ckfopen(char *, char *);
static void *ckmalloc(int);
static char *savestr(char *);
static void error(char *);
#define equal(s1, s2) (strcmp(s1, s2) == 0)
FILE *ckfopen();
char *savestr();
void *ckmalloc __P((int));
void error();
main(argc, argv)
char **argv;
{
int
main(int argc __unused, char *argv[])
{
char **ap;
int fd;
char c;
if (argc < 2)
error("Usage: mkinit command file...");
header_files[0] = "\"shell.h\"";
header_files[1] = "\"mystring.h\"";
for (ap = argv + 2 ; *ap ; ap++)
for (ap = argv + 1 ; *ap ; ap++)
readfile(*ap);
output();
if (file_changed()) {
unlink(OUTFILE);
link(OUTTEMP, OUTFILE);
unlink(OUTTEMP);
} else {
unlink(OUTTEMP);
if (touch(OUTOBJ))
exit(0); /* no compilation necessary */
}
printf("%s\n", argv[1]);
execl("/bin/sh", "sh", "-c", argv[1], (char *)0);
error("Can't exec shell");
rename(OUTTEMP, OUTFILE);
exit(0);
}
@@ -191,10 +188,9 @@ main(argc, argv)
* Parse an input file.
*/
void
readfile(fname)
char *fname;
{
static void
readfile(char *fname)
{
FILE *fp;
char line[1024];
struct event *ep;
@@ -215,19 +211,31 @@ readfile(fname)
doinclude(line);
if (line[0] == 'M' && match("MKINIT", line))
dodecl(line, fp);
if (line[0] == '#' && gooddefine(line))
if (line[0] == '#' && gooddefine(line)) {
char *cp;
char line2[1024];
static const char undef[] = "#undef ";
strcpy(line2, line);
memcpy(line2, undef, sizeof(undef) - 1);
cp = line2 + sizeof(undef) - 1;
while(*cp && (*cp == ' ' || *cp == '\t'))
cp++;
while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
cp++;
*cp++ = '\n'; *cp = '\0';
addstr(line2, &defines);
addstr(line, &defines);
}
}
fclose(fp);
}
int
match(name, line)
char *name;
char *line;
{
register char *p, *q;
static int
match(char *name, char *line)
{
char *p, *q;
p = name, q = line;
while (*p) {
@@ -240,11 +248,10 @@ match(name, line)
}
int
gooddefine(line)
char *line;
{
register char *p;
static int
gooddefine(char *line)
{
char *p;
if (! match("#define", line))
return 0; /* not a define */
@@ -264,12 +271,9 @@ gooddefine(line)
}
void
doevent(ep, fp, fname)
register struct event *ep;
FILE *fp;
char *fname;
{
static void
doevent(struct event *ep, FILE *fp, char *fname)
{
char line[1024];
int indent;
char *p;
@@ -304,13 +308,12 @@ doevent(ep, fp, fname)
}
void
doinclude(line)
char *line;
{
register char *p;
static void
doinclude(char *line)
{
char *p;
char *name;
register char **pp;
char **pp;
for (p = line ; *p != '"' && *p != '<' && *p != '\0' ; p++);
if (*p == '\0')
@@ -329,13 +332,11 @@ doinclude(line)
}
void
dodecl(line1, fp)
char *line1;
FILE *fp;
{
static void
dodecl(char *line1, FILE *fp)
{
char line[1024];
register char *p, *q;
char *p, *q;
if (strcmp(line1, "MKINIT\n") == 0) { /* start of struct/union decl */
addchar('\n', &decls);
@@ -350,7 +351,8 @@ dodecl(line1, fp)
if (! amiddecls)
addchar('\n', &decls);
q = NULL;
for (p = line1 + 6 ; *p != '=' && *p != '/' ; p++);
for (p = line1 + 6 ; *p && strchr("=/\n", *p) == NULL; p++)
continue;
if (*p == '=') { /* eliminate initialization */
for (q = p ; *q && *q != ';' ; q++);
if (*q == '\0')
@@ -375,8 +377,9 @@ dodecl(line1, fp)
* Write the output to the file OUTTEMP.
*/
void
output() {
static void
output(void)
{
FILE *fp;
char **pp;
struct event *ep;
@@ -392,7 +395,7 @@ output() {
for (ep = event ; ep->name ; ep++) {
fputs("\n\n\n", fp);
fputs(ep->comment, fp);
fprintf(fp, "\nvoid\n%s() {\n", ep->routine);
fprintf(fp, "\nvoid\n%s(void) {\n", ep->routine);
writetext(&ep->code, fp);
fprintf(fp, "}\n");
}
@@ -400,62 +403,15 @@ output() {
}
/*
* Return true if the new output file is different from the old one.
*/
int
file_changed() {
register FILE *f1, *f2;
register int c;
if ((f1 = fopen(OUTFILE, "r")) == NULL
|| (f2 = fopen(OUTTEMP, "r")) == NULL)
return 1;
while ((c = getc(f1)) == getc(f2)) {
if (c == EOF)
return 0;
}
return 1;
}
/*
* Touch a file. Returns 0 on failure, 1 on success.
*/
int
touch(file)
char *file;
{
int fd;
char c;
if ((fd = open(file, O_RDWR)) < 0)
return 0;
if (read(fd, &c, 1) != 1) {
close(fd);
return 0;
}
lseek(fd, 0L, 0);
write(fd, &c, 1);
close(fd);
return 1;
}
/*
* A text structure is simply a block of text that is kept in memory.
* Addstr appends a string to the text struct, and addchar appends a single
* character.
*/
void
addstr(s, text)
register char *s;
register struct text *text;
{
static void
addstr(char *s, struct text *text)
{
while (*s) {
if (--text->nleft < 0)
addchar(*s++, text);
@@ -465,10 +421,9 @@ addstr(s, text)
}
void
addchar(c, text)
register struct text *text;
{
static void
addchar(int c, struct text *text)
{
struct block *bp;
if (--text->nleft < 0) {
@@ -487,11 +442,9 @@ addchar(c, text)
/*
* Write the contents of a text structure to a file.
*/
void
writetext(text, fp)
struct text *text;
FILE *fp;
{
static void
writetext(struct text *text, FILE *fp)
{
struct block *bp;
if (text->start != NULL) {
@@ -501,47 +454,47 @@ writetext(text, fp)
}
}
FILE *
ckfopen(file, mode)
char *file;
char *mode;
{
static FILE *
ckfopen(char *file, char *mode)
{
FILE *fp;
if ((fp = fopen(file, mode)) == NULL) {
fprintf(stderr, "Can't open %s\n", file);
fprintf(stderr, "Can't open %s: %s\n", file, strerror(errno));
exit(2);
}
return fp;
}
void *
ckmalloc(nbytes) {
register char *p;
char *malloc();
static void *
ckmalloc(int nbytes)
{
char *p;
if ((p = malloc(nbytes)) == NULL)
error("Out of space");
return p;
}
char *
savestr(s)
char *s;
{
register char *p;
static char *
savestr(char *s)
{
char *p;
p = ckmalloc(strlen(s) + 1);
strcpy(p, s);
return p;
}
void
error(msg)
char *msg;
{
static void
error(char *msg)
{
if (curfile != NULL)
fprintf(stderr, "%s:%d: ", curfile, linno);
fprintf(stderr, "%s\n", msg);
exit(2);
}
/*
* $PchId: mkinit.c,v 1.6 2006/05/22 12:16:50 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,15 +30,20 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mknodes.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95";
#endif /* not lint */
#endif
/*
__FBSDID("$FreeBSD: src/bin/sh/mknodes.c,v 1.17 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program reads the nodetypes file and nodes.c.pat file. It generates
@@ -50,7 +51,10 @@ static char sccsid[] = "@(#)mknodes.c 5.1 (Berkeley) 3/7/91";
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#define MAXTYPES 50 /* max number of node types */
#define MAXFIELDS 20 /* max fields in a structure */
@@ -80,31 +84,42 @@ struct str { /* struct representing a node structure */
};
int ntypes; /* number of node types */
char *nodename[MAXTYPES]; /* names of the nodes */
struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
int nstr; /* number of structures */
struct str str[MAXTYPES]; /* the structures */
struct str *curstr; /* current structure */
static int ntypes; /* number of node types */
static char *nodename[MAXTYPES]; /* names of the nodes */
static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */
static int nstr; /* number of structures */
static struct str str[MAXTYPES]; /* the structures */
static struct str *curstr; /* current structure */
static FILE *infp;
static char line[1024];
static int linno;
static char *linep;
#ifndef __printf0like
#define __printf0like(a,b)
#endif
static void parsenode(void);
static void parsefield(void);
static void output(char *);
static void outsizes(FILE *);
static void outfunc(FILE *, int);
static void indent(int, FILE *);
static int nextfield(char *);
static void skipbl(void);
static int readline(void);
static void error(const char *, ...) __printf0like(1, 2);
static char *savestr(const char *);
FILE *infp = stdin;
char line[1024];
int linno;
char *linep;
char *savestr();
#define equal(s1, s2) (strcmp(s1, s2) == 0)
main(argc, argv)
char **argv;
{
int
main(int argc, char *argv[])
{
if (argc != 3)
error("usage: mknodes file\n");
error("usage: mknodes file");
infp = stdin;
if ((infp = fopen(argv[1], "r")) == NULL)
error("Can't open %s", argv[1]);
error("Can't open %s: %s", argv[1], strerror(errno));
while (readline()) {
if (line[0] == ' ' || line[0] == '\t')
parsefield();
@@ -112,12 +127,14 @@ main(argc, argv)
parsenode();
}
output(argv[2]);
return 0;
exit(0);
}
parsenode() {
static void
parsenode(void)
{
char name[BUFLEN];
char tag[BUFLEN];
struct str *sp;
@@ -131,7 +148,7 @@ parsenode() {
error("Garbage at end of line");
nodename[ntypes] = savestr(name);
for (sp = str ; sp < str + nstr ; sp++) {
if (equal(sp->tag, tag))
if (strcmp(sp->tag, tag) == 0)
break;
}
if (sp >= str + nstr) {
@@ -145,7 +162,9 @@ parsenode() {
}
parsefield() {
static void
parsefield(void)
{
char name[BUFLEN];
char type[BUFLEN];
char decl[2 * BUFLEN];
@@ -159,21 +178,21 @@ parsefield() {
error("No field type");
fp = &curstr->field[curstr->nfields];
fp->name = savestr(name);
if (equal(type, "nodeptr")) {
if (strcmp(type, "nodeptr") == 0) {
fp->type = T_NODE;
sprintf(decl, "union node *%s", name);
} else if (equal(type, "nodelist")) {
} else if (strcmp(type, "nodelist") == 0) {
fp->type = T_NODELIST;
sprintf(decl, "struct nodelist *%s", name);
} else if (equal(type, "string")) {
} else if (strcmp(type, "string") == 0) {
fp->type = T_STRING;
sprintf(decl, "char *%s", name);
} else if (equal(type, "int")) {
} else if (strcmp(type, "int") == 0) {
fp->type = T_INT;
sprintf(decl, "int %s", name);
} else if (equal(type, "other")) {
} else if (strcmp(type, "other") == 0) {
fp->type = T_OTHER;
} else if (equal(type, "temp")) {
} else if (strcmp(type, "temp") == 0) {
fp->type = T_TEMP;
} else {
error("Unknown type %s", type);
@@ -196,9 +215,9 @@ char writer[] = "\
*/\n\
\n";
output(file)
char *file;
{
static void
output(char *file)
{
FILE *hfile;
FILE *cfile;
FILE *patfile;
@@ -208,9 +227,9 @@ output(file)
char *p;
if ((patfile = fopen(file, "r")) == NULL)
error("Can't open %s", file);
error("Can't open %s: %s", file, strerror(errno));
if ((hfile = fopen("nodes.h", "w")) == NULL)
error("Can't create nodes.h");
error("Can't create nodes.h: %s", strerror(errno));
if ((cfile = fopen("nodes.c", "w")) == NULL)
error("Can't create nodes.c");
fputs(writer, hfile);
@@ -234,22 +253,17 @@ output(file)
fputs("\tstruct nodelist *next;\n", hfile);
fputs("\tunion node *n;\n", hfile);
fputs("};\n\n\n", hfile);
fputs("#ifdef __STDC__\n", hfile);
fputs("union node *copyfunc(union node *);\n", hfile);
fputs("void freefunc(union node *);\n", hfile);
fputs("#else\n", hfile);
fputs("union node *copyfunc();\n", hfile);
fputs("void freefunc();\n", hfile);
fputs("#endif\n", hfile);
fputs(writer, cfile);
while (fgets(line, sizeof line, patfile) != NULL) {
for (p = line ; *p == ' ' || *p == '\t' ; p++);
if (equal(p, "%SIZES\n"))
if (strcmp(p, "%SIZES\n") == 0)
outsizes(cfile);
else if (equal(p, "%CALCSIZE\n"))
else if (strcmp(p, "%CALCSIZE\n") == 0)
outfunc(cfile, 1);
else if (equal(p, "%COPY\n"))
else if (strcmp(p, "%COPY\n") == 0)
outfunc(cfile, 0);
else
fputs(line, cfile);
@@ -258,9 +272,9 @@ output(file)
outsizes(cfile)
FILE *cfile;
{
static void
outsizes(FILE *cfile)
{
int i;
fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes);
@@ -271,9 +285,9 @@ outsizes(cfile)
}
outfunc(cfile, calcsize)
FILE *cfile;
{
static void
outfunc(FILE *cfile, int calcsize)
{
struct str *sp;
struct field *fp;
int i;
@@ -287,8 +301,7 @@ outfunc(cfile, calcsize)
fputs(" funcblocksize += nodesize[n->type];\n", cfile);
else {
fputs(" new = funcblock;\n", cfile);
fputs(" *(char **)&funcblock += nodesize[n->type];\n",
cfile);
fputs(" funcblock = (char *)funcblock + nodesize[n->type];\n", cfile);
}
fputs(" switch (n->type) {\n", cfile);
for (sp = str ; sp < &str[nstr] ; sp++) {
@@ -351,9 +364,9 @@ outfunc(cfile, calcsize)
}
indent(amount, fp)
FILE *fp;
{
static void
indent(int amount, FILE *fp)
{
while (amount >= 8) {
putc('\t', fp);
amount -= 8;
@@ -364,11 +377,10 @@ indent(amount, fp)
}
int
nextfield(buf)
char *buf;
{
register char *p, *q;
static int
nextfield(char *buf)
{
char *p, *q;
p = linep;
while (*p == ' ' || *p == '\t')
@@ -382,15 +394,18 @@ nextfield(buf)
}
skipbl() {
static void
skipbl(void)
{
while (*linep == ' ' || *linep == '\t')
linep++;
}
int
readline() {
register char *p;
static int
readline(void)
{
char *p;
if (fgets(line, 1024, infp) == NULL)
return 0;
@@ -407,26 +422,34 @@ readline() {
error(msg, a1, a2, a3, a4, a5, a6)
char *msg;
{
fprintf(stderr, "line %d: ", linno);
fprintf(stderr, msg, a1, a2, a3, a4, a5, a6);
putc('\n', stderr);
static void
error(const char *msg, ...)
{
va_list va;
va_start(va, msg);
(void) fprintf(stderr, "line %d: ", linno);
(void) vfprintf(stderr, msg, va);
(void) fputc('\n', stderr);
va_end(va);
exit(2);
}
char *
savestr(s)
char *s;
{
register char *p;
char *malloc();
static char *
savestr(const char *s)
{
char *p;
if ((p = malloc(strlen(s) + 1)) == NULL)
error("Out of space");
strcpy(p, s);
(void) strcpy(p, s);
return p;
}
/*
* $PchId: mknodes.c,v 1.6 2006/05/23 12:05:14 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -35,23 +35,23 @@
*/
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mksignames.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)mksignames.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
/*
* This program generates the signames.h and signames.c files.
*/
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
int main(int argc, char *argv[]);
struct sig {
int signo; /* signal number */
@@ -198,3 +198,7 @@ main(argc, argv) char **argv; {
fprintf(cfile, "};\n");
exit(0);
}
/*
* $PchId: mksignames.c,v 1.2 2001/05/14 19:22:26 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -34,23 +30,33 @@
* SUCH DAMAGE.
*/
#if 0
#ifndef lint
char copyright[] =
"@(#) Copyright (c) 1991 The Regents of the University of California.\n\
All rights reserved.\n";
static char const copyright[] =
"@(#) Copyright (c) 1991, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
static char sccsid[] = "@(#)mksyntax.c 5.2 (Berkeley) 3/8/91";
static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95";
#endif /* not lint */
#endif
/*
__FBSDID("$FreeBSD: src/bin/sh/mksyntax.c,v 1.23 2004/04/06 20:06:51 markm Exp $");
*/
/*
* This program creates syntax.h and syntax.c.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "parser.h"
#ifdef __minix
#define __unused
#endif
struct synclass {
char *name;
@@ -59,19 +65,21 @@ struct synclass {
/* Syntax classes */
struct synclass synclass[] = {
"CWORD", "character is nothing special",
"CNL", "newline character",
"CBACK", "a backslash character",
"CSQUOTE", "single quote",
"CDQUOTE", "double quote",
"CENDQUOTE", "a terminating quote",
"CBQUOTE", "backwards single quote",
"CVAR", "a dollar sign",
"CENDVAR", "a '}' character",
"CEOF", "end of file",
"CCTL", "like CWORD, except it must be escaped",
"CSPCL", "these terminate a word",
NULL, NULL
{ "CWORD", "character is nothing special" },
{ "CNL", "newline character" },
{ "CBACK", "a backslash character" },
{ "CSQUOTE", "single quote" },
{ "CDQUOTE", "double quote" },
{ "CENDQUOTE", "a terminating quote" },
{ "CBQUOTE", "backwards single quote" },
{ "CVAR", "a dollar sign" },
{ "CENDVAR", "a '}' character" },
{ "CLP", "a left paren in arithmetic" },
{ "CRP", "a right paren in arithmetic" },
{ "CEOF", "end of file" },
{ "CCTL", "like CWORD, except it must be escaped" },
{ "CSPCL", "these terminate a word" },
{ NULL, NULL }
};
@@ -80,31 +88,39 @@ struct synclass synclass[] = {
* you may have to change the definition of the is_in_name macro.
*/
struct synclass is_entry[] = {
"ISDIGIT", "a digit",
"ISUPPER", "an upper case letter",
"ISLOWER", "a lower case letter",
"ISUNDER", "an underscore",
"ISSPECL", "the name of a special parameter",
NULL, NULL,
{ "ISDIGIT", "a digit" },
{ "ISUPPER", "an upper case letter" },
{ "ISLOWER", "a lower case letter" },
{ "ISUNDER", "an underscore" },
{ "ISSPECL", "the name of a special parameter" },
{ NULL, NULL }
};
char writer[] = "\
static char writer[] = "\
/*\n\
* This file was generated by the mksyntax program.\n\
*/\n\
\n";
FILE *cfile;
FILE *hfile;
char *syntax[513];
int base;
int size; /* number of values which a char variable can have */
int nbits; /* number of bits in a character */
int digit_contig; /* true if digits are contiguous */
static FILE *cfile;
static FILE *hfile;
static char *syntax[513];
static int base;
static int size; /* number of values which a char variable can have */
static int nbits; /* number of bits in a character */
static int digit_contig;/* true if digits are contiguous */
static void filltable(char *);
static void init(void);
static void add(char *, char *);
static void print(char *);
static void output_type_macros(void);
static void digit_convert(void);
main() {
int
main(int argc __unused, char **argv __unused)
{
char c;
char d;
int sign;
@@ -136,7 +152,9 @@ main() {
if (d == c)
break;
}
#if 0
printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits);
#endif
if (nbits > 9) {
fputs("Characters can't have more than 9 bits\n", stderr);
exit(2);
@@ -151,14 +169,14 @@ main() {
digit_contig = 0;
}
fputs("#include <sys/cdefs.h>\n", hfile);
fputs("#include <ctype.h>\n", hfile);
/* Generate the #define statements in the header file */
fputs("/* Syntax classes */\n", hfile);
for (i = 0 ; synclass[i].name ; i++) {
sprintf(buf, "#define %s %d", synclass[i].name, i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", synclass[i].comment);
}
@@ -167,7 +185,7 @@ main() {
for (i = 0 ; is_entry[i].name ; i++) {
sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i);
fputs(buf, hfile);
for (pos = strlen(buf) ; pos < 32 ; pos = pos + 8 &~ 07)
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07)
putc('\t', hfile);
fprintf(hfile, "/* %s */\n", is_entry[i].comment);
}
@@ -178,6 +196,7 @@ main() {
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile);
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile);
fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile);
fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile);
putc('\n', hfile);
output_type_macros(); /* is_digit, etc. */
putc('\n', hfile);
@@ -204,14 +223,28 @@ main() {
add("`", "CBQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("!*?[=", "CCTL");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("dqsyntax");
init();
fputs("\n/* syntax table used when in single quotes */\n", cfile);
add("\n", "CNL");
add("'", "CENDQUOTE");
add("!*?[=", "CCTL");
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */
add("!*?[=~:/-", "CCTL");
print("sqsyntax");
init();
fputs("\n/* syntax table used when in arithmetic */\n", cfile);
add("\n", "CNL");
add("\\", "CBACK");
add("`", "CBQUOTE");
add("'", "CSQUOTE");
add("\"", "CDQUOTE");
add("$", "CVAR");
add("}", "CENDVAR");
add("(", "CLP");
add(")", "CRP");
print("arisyntax");
filltable("0");
fputs("\n/* character classification table */\n", cfile);
add("0123456789", "ISDIGIT");
@@ -231,9 +264,9 @@ main() {
* Clear the syntax table.
*/
filltable(dftval)
char *dftval;
{
static void
filltable(char *dftval)
{
int i;
for (i = 0 ; i < size ; i++)
@@ -245,7 +278,9 @@ filltable(dftval)
* Initialize the syntax table with default values.
*/
init() {
static void
init(void)
{
filltable("CWORD");
syntax[0] = "CEOF";
syntax[base + CTLESC] = "CCTL";
@@ -253,6 +288,9 @@ init() {
syntax[base + CTLENDVAR] = "CCTL";
syntax[base + CTLBACKQ] = "CCTL";
syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL";
syntax[base + CTLARI] = "CCTL";
syntax[base + CTLENDARI] = "CCTL";
syntax[base + CTLQUOTEMARK] = "CCTL";
}
@@ -260,9 +298,9 @@ init() {
* Add entries to the syntax table.
*/
add(p, type)
char *p, *type;
{
static void
add(char *p, char *type)
{
while (*p)
syntax[*p++ + base] = type;
}
@@ -273,9 +311,9 @@ add(p, type)
* Output the syntax table.
*/
print(name)
char *name;
{
static void
print(char *name)
{
int i;
int col;
@@ -306,16 +344,18 @@ print(name)
* contiguous, we can test for them quickly.
*/
char *macro[] = {
static char *macro[] = {
"#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)",
"#define is_alpha(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER))",
"#define is_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER))",
"#define is_in_name(c)\t((is_type+SYNBASE)[c] & (ISUPPER|ISLOWER|ISUNDER|ISDIGIT))",
"#define is_alpha(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && isalpha((unsigned char) (c)))",
"#define is_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalpha((unsigned char) (c))))",
"#define is_in_name(c)\t((c) != PEOF && ((c) < CTLESC || (c) > CTLQUOTEMARK) && ((c) == '_' || isalnum((unsigned char) (c))))",
"#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))",
NULL
};
output_type_macros() {
static void
output_type_macros(void)
{
char **pp;
if (digit_contig)
@@ -334,7 +374,9 @@ output_type_macros() {
* Output digit conversion table (if digits are not contiguous).
*/
digit_convert() {
static void
digit_convert(void)
{
int maxdigit;
static char digit[] = "0123456789";
char *p;
@@ -350,7 +392,11 @@ digit_convert() {
for (p = digit ; *p && *p != i ; p++);
if (*p == '\0')
p = digit;
fprintf(cfile, " %d,\n", p - digit);
fprintf(cfile, " %d,\n", (int)(p - digit));
}
fputs("};\n", cfile);
}
/*
* $PchId: mksyntax.c,v 1.7 2006/05/23 12:04:27 philip Exp $
*/

View File

@@ -1,7 +1,7 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +14,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,7 +30,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)mktokens 5.1 (Berkeley) 3/7/91
# @(#)mktokens 8.1 (Berkeley) 5/31/93
# $FreeBSD: src/bin/sh/mktokens,v 1.9 2004/04/06 20:06:51 markm Exp $
# All calls to awk removed, because Minix bawk is deficient. (kjb)
@@ -42,7 +39,9 @@
# token marks the end of a list. The third column is the name to print in
# error messages.
cat > /tmp/ka$$ <<\!
#temp=`/usr/bin/mktemp -t ka`
temp=/tmp/mkt$$
cat > $temp <<\!
TEOF 1 end of file
TNL 0 newline
TSEMI 0 ";"
@@ -70,16 +69,17 @@ TBEGIN 0 "{"
TEND 1 "}"
TCASE 0 "case"
TESAC 1 "esac"
TNOT 0 "!"
!
nl=`wc -l /tmp/ka$$`
exec > token.def
nl=`wc -l $temp`
exec > token.h
i=0
while read line
do
set -$- $line
echo "#define $1 $i"
i=`expr $i + 1`
done </tmp/ka$$
done <$temp
echo '
/* Array indicating which tokens mark the end of a list */
const char tokendlist[] = {'
@@ -87,18 +87,18 @@ while read line
do
set -$- $line
echo " $2,"
done </tmp/ka$$
done <$temp
echo '};
char *const tokname[] = {'
const char *const tokname[] = {'
sed -e 's/"/\\"/g' \
-e 's/[^ ]*[ ][ ]*[^ ]*[ ][ ]*\(.*\)/ "\1",/' \
/tmp/ka$$
$temp
echo '};
'
i=0
go=
sed 's/"//g' /tmp/ka$$ |
sed 's/"//g' $temp |
while read line
do
set -$- $line
@@ -106,7 +106,7 @@ sed 's/"//g' /tmp/ka$$ |
then
echo "#define KWDOFFSET $i"
echo
echo "char *const parsekwd[] = {"
echo "const char *const parsekwd[] = {"
go=true
fi
if [ "$go" ]
@@ -118,4 +118,7 @@ sed 's/"//g' /tmp/ka$$ |
echo ' 0
};'
rm /tmp/ka$$
rm $temp
#
# $PchId: mktokens,v 1.5 2006/05/22 12:43:35 philip Exp $

50
commands/ash/myhistedit.h Normal file
View File

@@ -0,0 +1,50 @@
/*-
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)myhistedit.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/myhistedit.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
#include <histedit.h>
extern History *hist;
extern EditLine *el;
extern int displayhist;
void histedit(void);
void sethistsize(const char *);
int histcmd(int, char **);
int bindcmd(int, char **);
/* From libedit */
void re_goto_bottom(EditLine *);
/*
* $PchId: myhistedit.h,v 1.5 2006/03/29 15:55:18 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,14 @@
*/
#ifndef lint
static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/mystring.c,v 1.13 2004/04/06 20:06:51 markm Exp $");
*/
/*
* String functions.
@@ -44,12 +46,11 @@ static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
* equal(s1, s2) Return true if strings are equal.
* scopy(from, to) Copy a string.
* scopyn(from, to, n) Like scopy, but checks for overflow.
* strchr(s, c) Find first occurance of c in s.
* bcopy(from, to, n) Copy a block of memory.
* number(s) Convert a string of digits to an integer.
* is_number(s) Return true if s is a string of digits.
*/
#include <stdlib.h>
#include "shell.h"
#include "syntax.h"
#include "error.h"
@@ -58,6 +59,14 @@ static char sccsid[] = "@(#)mystring.c 5.1 (Berkeley) 3/7/91";
char nullstr[1]; /* zero length string */
/*
* equal - #defined in mystring.h
*/
/*
* scopy - #defined in mystring.h
*/
/*
* scopyn - copy a string from "from" to "to", truncating the string
@@ -66,11 +75,8 @@ char nullstr[1]; /* zero length string */
*/
void
scopyn(from, to, size)
register char const *from;
register char *to;
register int size;
{
scopyn(const char *from, char *to, int size)
{
while (--size > 0) {
if ((*to++ = *from++) == '\0')
@@ -80,59 +86,13 @@ scopyn(from, to, size)
}
/*
* strchr - find first occurrence of a character in a string.
*/
#ifndef SYS5
char *
mystrchr(s, charwanted)
char const *s;
register char charwanted;
{
register char const *scan;
/*
* The odd placement of the two tests is so NUL is findable.
*/
for (scan = s ; *scan != charwanted ; ) /* ++ moved down for opt. */
if (*scan++ == '\0')
return NULL;
return (char *)scan;
}
#endif
/*
* bcopy - copy bytes
*
* This routine was derived from code by Henry Spencer.
*/
void
mybcopy(src, dst, length)
pointer dst;
const pointer src;
register int length;
{
register char *d = dst;
register char *s = src;
while (--length >= 0)
*d++ = *s++;
}
/*
* prefix -- see if pfx is a prefix of string.
*/
int
prefix(pfx, string)
register char const *pfx;
register char const *string;
{
prefix(const char *pfx, const char *string)
{
while (*pfx) {
if (*pfx++ != *string++)
return 0;
@@ -147,12 +107,10 @@ prefix(pfx, string)
*/
int
number(s)
const char *s;
{
number(const char *s)
{
if (! is_number(s))
error2("Illegal number", (char *)s);
error("Illegal number: %s", (char *)s);
return atoi(s);
}
@@ -163,12 +121,15 @@ number(s)
*/
int
is_number(p)
register const char *p;
{
is_number(const char *p)
{
do {
if (! is_digit(*p))
return 0;
} while (*++p != '\0');
return 1;
}
/*
* $PchId: mystring.c,v 1.4 2006/05/22 12:21:53 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,39 +29,20 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mystring.h 5.1 (Berkeley) 3/7/91
* @(#)mystring.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/mystring.h,v 1.8 2004/04/06 20:06:51 markm Exp $
*/
#ifndef SYSV
#define strchr mystrchr
#endif
#include <string.h>
#ifdef __STDC__
void scopyn(const char *, char *, int);
char *strchr(const char *, int);
void mybcopy(const pointer, pointer, int);
int prefix(const char *, const char *);
int number(const char *);
int is_number(const char *);
int strcmp(const char *, const char *); /* from C library */
char *strcpy(char *, const char *); /* from C library */
int strlen(const char *); /* from C library */
char *strcat(char *, const char *); /* from C library */
char *strerror(int); /* from C library */
#else
void scopyn();
char *strchr();
void mybcopy();
int prefix();
int number();
int is_number();
int strcmp();
char *strcpy();
int strlen();
char *strcat();
char *strerror();
#endif
#define equal(s1, s2) (strcmp(s1, s2) == 0)
#define scopy(s1, s2) ((void)strcpy(s2, s1))
#define bcopy(src, dst, n) mybcopy((pointer)(src), (pointer)(dst), n)
/*
* $PchId: mystring.h,v 1.3 2006/03/29 15:49:08 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,9 +29,11 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)nodes.c.pat 5.2 (Berkeley) 3/8/91
* @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/nodes.c.pat,v 1.15 2004/04/06 20:06:51 markm Exp $
*/
#include <stdlib.h>
/*
* Routine for dealing with parsed shell commands.
*/
@@ -43,35 +41,26 @@
#include "shell.h"
#include "nodes.h"
#include "memalloc.h"
#include "machdep.h"
#include "mystring.h"
int funcblocksize; /* size of structures in function */
int funcstringsize; /* size of strings in node */
#ifdef __STDC__
pointer funcblock; /* block to allocate function from */
#else
char *funcblock; /* block to allocate function from */
#ifndef __minix
#include <sys/param.h>
#endif
char *funcstring; /* block to allocate strings from */
#include "machdep.h"
STATIC int funcblocksize; /* size of structures in function */
STATIC int funcstringsize; /* size of strings in node */
STATIC pointer funcblock; /* block to allocate function from */
STATIC char *funcstring; /* block to allocate strings from */
%SIZES
#ifdef __STDC__
STATIC void calcsize(union node *);
STATIC void sizenodelist(struct nodelist *);
STATIC union node *copynode(union node *);
STATIC struct nodelist *copynodelist(struct nodelist *);
STATIC char *nodesavestr(char *);
#else
STATIC void calcsize();
STATIC void sizenodelist();
STATIC union node *copynode();
STATIC struct nodelist *copynodelist();
STATIC char *nodesavestr();
#endif
@@ -80,86 +69,81 @@ STATIC char *nodesavestr();
*/
union node *
copyfunc(n)
union node *n;
{
if (n == NULL)
return NULL;
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *)funcblock + funcblocksize;
return copynode(n);
copyfunc(union node *n)
{
if (n == NULL)
return NULL;
funcblocksize = 0;
funcstringsize = 0;
calcsize(n);
funcblock = ckmalloc(funcblocksize + funcstringsize);
funcstring = (char *)funcblock + funcblocksize;
return copynode(n);
}
STATIC void
calcsize(n)
union node *n;
{
%CALCSIZE
calcsize(union node *n)
{
%CALCSIZE
}
STATIC void
sizenodelist(lp)
struct nodelist *lp;
{
while (lp) {
funcblocksize += ALIGN(sizeof (struct nodelist));
calcsize(lp->n);
lp = lp->next;
}
sizenodelist(struct nodelist *lp)
{
while (lp) {
funcblocksize += ALIGN(sizeof(struct nodelist));
calcsize(lp->n);
lp = lp->next;
}
}
STATIC union node *
copynode(n)
union node *n;
{
union node *new;
copynode(union node *n)
{
union node *new;
%COPY
return new;
%COPY
return new;
}
STATIC struct nodelist *
copynodelist(lp)
struct nodelist *lp;
{
struct nodelist *start;
struct nodelist **lpp;
copynodelist(struct nodelist *lp)
{
struct nodelist *start;
struct nodelist **lpp;
lpp = &start;
while (lp) {
*lpp = funcblock;
*(char **)&funcblock += ALIGN(sizeof (struct nodelist));
(*lpp)->n = copynode(lp->n);
lp = lp->next;
lpp = &(*lpp)->next;
}
*lpp = NULL;
return start;
lpp = &start;
while (lp) {
*lpp = funcblock;
funcblock = (char *)funcblock + ALIGN(sizeof(struct nodelist));
(*lpp)->n = copynode(lp->n);
lp = lp->next;
lpp = &(*lpp)->next;
}
*lpp = NULL;
return start;
}
STATIC char *
nodesavestr(s)
char *s;
{
register char *p = s;
register char *q = funcstring;
char *rtn = funcstring;
nodesavestr(char *s)
{
char *p = s;
char *q = funcstring;
char *rtn = funcstring;
while (*q++ = *p++);
funcstring = q;
return rtn;
while ((*q++ = *p++) != '\0')
continue;
funcstring = q;
return rtn;
}
@@ -169,9 +153,12 @@ nodesavestr(s)
*/
void
freefunc(n)
union node *n;
{
if (n)
ckfree(n);
freefunc(union node *n)
{
if (n)
ckfree(n);
}
/*
* $PchId: nodes.c.pat,v 1.5 2006/05/22 12:43:57 philip Exp $
*/

View File

@@ -1,7 +1,6 @@
#!/bin/sh -
#
# Copyright (c) 1991 The Regents of the University of California.
# All rights reserved.
# Copyright (c) 1991, 1993
# The Regents of the University of California. All rights reserved.
#
# This code is derived from software contributed to Berkeley by
# Kenneth Almquist.
@@ -14,10 +13,6 @@
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
@@ -34,7 +29,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# @(#)nodetypes 5.1 (Berkeley) 3/7/91
# @(#)nodetypes 8.2 (Berkeley) 5/4/95
# $FreeBSD: src/bin/sh/nodetypes,v 1.9 2004/04/06 20:06:51 markm Exp $
# This file describes the nodes used in parse trees. Unindented lines
# contain a node type followed by a structure tag. Subsequent indented
@@ -118,7 +114,9 @@ NARG narg # represents a word
NTO nfile # fd> fname
NFROM nfile # fd< fname
NFROMTO nfile # fd<> fname
NAPPEND nfile # fd>> fname
NCLOBBER nfile # fd>| fname
type int
next nodeptr # next redirection in list
fd int # file descriptor being redirected
@@ -131,6 +129,8 @@ NFROMFD ndup # fd>&dupfd
next nodeptr # next redirection in list
fd int # file descriptor being redirected
dupfd int # file descriptor to duplicate
vname nodeptr # file name if fd>&$var
NHERE nhere # fd<<\!
NXHERE nhere # fd<<!
@@ -138,3 +138,10 @@ NXHERE nhere # fd<<!
next nodeptr # next redirection in list
fd int # file descriptor being redirected
doc nodeptr # input to command (NARG node)
NNOT nnot # ! command (actually pipeline)
type int
com nodeptr
#
# $PchId: nodetypes,v 1.3 2006/03/29 15:43:35 philip Exp $

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,18 @@
*/
#ifndef lint
static char sccsid[] = "@(#)options.c 5.2 (Berkeley) 3/13/91";
#if 0
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/options.c,v 1.21 2004/04/06 20:06:51 markm Exp $");
*/
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#define DEFINE_OPTIONS
@@ -52,25 +58,25 @@ static char sccsid[] = "@(#)options.c 5.2 (Berkeley) 3/13/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "builtins.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
char *arg0; /* value of $0 */
struct shparam shellparam; /* current positional parameters */
char **argptr; /* argument list for builtin commands */
char *optarg; /* set by nextopt (like getopt) */
char *shoptarg; /* set by nextopt (like getopt) */
char *optptr; /* used by nextopt */
int editable; /* isatty(0) && isatty(1) */
int editable; /* isatty(0) && isatty(1) */
char *minusc; /* argument to -c option */
#ifdef __STDC__
STATIC void options(int);
STATIC void minus_o(char *, int);
STATIC void setoption(int, int);
#else
STATIC void options();
STATIC void setoption();
#endif
STATIC int getopts(char *, char *, char **, char ***, char **);
/*
@@ -78,46 +84,56 @@ STATIC void setoption();
*/
void
procargs(argc, argv)
char **argv;
{
char *p;
procargs(int argc, char **argv)
{
int i;
argptr = argv;
if (argc > 0)
argptr++;
for (p = optval ; p < optval + sizeof optval - 1 ; p++)
*p = 2;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 2;
privileged = (getuid() != geteuid() || getgid() != getegid());
options(1);
if (*argptr == NULL && minusc == NULL)
sflag = 1;
editable = (isatty(0) && isatty(1));
if (iflag == 2 && sflag == 1 && editable)
iflag = 1;
if (jflag == 2)
jflag = iflag;
for (p = optval ; p < optval + sizeof optval - 1 ; p++)
if (*p == 2)
*p = 0;
if (mflag == 2)
mflag = iflag;
for (i = 0; i < NOPTS; i++)
if (optlist[i].val == 2)
optlist[i].val = 0;
arg0 = argv[0];
if (sflag == 0) {
arg0 = *argptr++;
if (minusc == NULL) {
commandname = arg0;
setinputfile(commandname, 0);
}
if (sflag == 0 && minusc == NULL) {
commandname = arg0 = *argptr++;
setinputfile(commandname, 0);
}
/* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */
if (argptr && minusc && *argptr)
arg0 = *argptr++;
shellparam.p = argptr;
shellparam.reset = 1;
/* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */
while (*argptr) {
shellparam.nparam++;
argptr++;
}
setinteractive(iflag);
setjobctl(jflag);
optschanged();
}
void
optschanged(void)
{
setinteractive(iflag);
#if !defined(NO_HISTORY) && !defined(EDITLINE)
histedit();
#endif
setjobctl(mflag);
}
/*
* Process shell options. The global variable argptr contains a pointer
@@ -125,8 +141,9 @@ procargs(argc, argv)
*/
STATIC void
options(cmdline) {
register char *p;
options(int cmdline)
{
char *p;
int val;
int c;
@@ -136,14 +153,14 @@ options(cmdline) {
argptr++;
if ((c = *p++) == '-') {
val = 1;
if (p[0] == '\0' || p[0] == '-' && p[1] == '\0') {
if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) {
if (!cmdline) {
/* "-" means turn off -x and -v */
if (p[0] == '\0')
xflag = vflag = 0;
/* "--" means reset params */
else if (*argptr == NULL)
setparam(argptr);
setparam(argptr);
}
break; /* "-" or "--" terminates options */
}
@@ -166,26 +183,79 @@ options(cmdline) {
#ifdef NOHACK
break;
#endif
} else if (c == 'o') {
minus_o(*argptr, val);
if (*argptr)
argptr++;
} else {
if (c == 'p' && !val && privileged) {
(void) setuid(getuid());
(void) setgid(getgid());
}
setoption(c, val);
}
}
if (! cmdline)
break;
}
}
STATIC void
minus_o(char *name, int val)
{
int doneset, i;
if (name == NULL) {
if (val) {
/* "Pretty" output. */
out1str("Current option settings\n");
for (i = 0; i < NOPTS; i++)
out1fmt("%-16s%s\n", optlist[i].name,
optlist[i].val ? "on" : "off");
} else {
/* Output suitable for re-input to shell. */
for (doneset = i = 0; i < NOPTS; i++)
if (optlist[i].val) {
if (!doneset) {
out1str("set");
doneset = 1;
}
out1fmt(" -o %s", optlist[i].name);
}
if (doneset)
out1c('\n');
}
} else {
for (i = 0; i < NOPTS; i++)
if (equal(name, optlist[i].name)) {
if (!val && privileged && equal(name, "privileged")) {
(void) setuid(getuid());
(void) setgid(getgid());
}
setoption(optlist[i].letter, val);
return;
}
error("Illegal option -o %s", name);
}
}
STATIC void
setoption(flag, val)
char flag;
int val;
{
register char *p;
setoption(int flag, int val)
{
int i;
if ((p = strchr(optchar, flag)) == NULL)
error("Illegal option -%c", flag);
optval[p - optchar] = val;
for (i = 0; i < NOPTS; i++)
if (optlist[i].letter == flag) {
optlist[i].val = val;
if (val) {
/* #%$ hack for ksh semantics */
if (flag == 'V')
Eflag = 0;
else if (flag == 'E')
Vflag = 0;
}
return;
}
error("Illegal option -%c", flag);
}
@@ -194,10 +264,12 @@ setoption(flag, val)
INCLUDE "options.h"
SHELLPROC {
char *p;
int i;
for (i = 0; i < NOPTS; i++)
optlist[i].val = 0;
optschanged();
for (p = optval ; p < optval + sizeof optval ; p++)
*p = 0;
}
#endif
@@ -207,9 +279,8 @@ SHELLPROC {
*/
void
setparam(argv)
char **argv;
{
setparam(char **argv)
{
char **newparam;
char **ap;
int nparam;
@@ -233,9 +304,8 @@ setparam(argv)
*/
void
freeparam(param)
struct shparam *param;
{
freeparam(struct shparam *param)
{
char **ap;
if (param->malloc) {
@@ -251,7 +321,9 @@ freeparam(param)
* The shift builtin command.
*/
shiftcmd(argc, argv) char **argv; {
int
shiftcmd(int argc, char **argv)
{
int n;
char **ap1, **ap2;
@@ -259,7 +331,7 @@ shiftcmd(argc, argv) char **argv; {
if (argc > 1)
n = number(argv[1]);
if (n > shellparam.nparam)
n = shellparam.nparam;
error("can't shift that many");
INTOFF;
shellparam.nparam -= n;
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) {
@@ -279,13 +351,14 @@ shiftcmd(argc, argv) char **argv; {
* The set command builtin.
*/
setcmd(argc, argv) char **argv; {
int
setcmd(int argc, char **argv)
{
if (argc == 1)
return showvarscmd(argc, argv);
INTOFF;
options(0);
setinteractive(iflag);
setjobctl(jflag);
optschanged();
if (*argptr != NULL) {
setparam(argptr);
}
@@ -294,6 +367,15 @@ setcmd(argc, argv) char **argv; {
}
void
getoptsreset(const char *value)
{
if (number(value) == 1) {
shellparam.optnext = NULL;
shellparam.reset = 1;
}
}
/*
* The getopts builtin. Shellparam.optnext points to the next argument
* to be processed. Shellparam.optptr points to the next character to
@@ -301,63 +383,127 @@ setcmd(argc, argv) char **argv; {
* then it's the first time getopts has been called.
*/
getoptscmd(argc, argv) char **argv; {
register char *p, *q;
char c;
int
getoptscmd(int argc, char **argv)
{
char **optbase = NULL;
if (argc < 3)
error("usage: getopts optstring var [arg]");
else if (argc == 3)
optbase = shellparam.p;
else
optbase = &argv[3];
if (shellparam.reset == 1) {
shellparam.optnext = optbase;
shellparam.optptr = NULL;
shellparam.reset = 0;
}
return getopts(argv[1], argv[2], optbase, &shellparam.optnext,
&shellparam.optptr);
}
STATIC int
getopts(char *optstr, char *optvar, char **optfirst, char ***optnext,
char **optptr)
{
char *p, *q;
char c = '?';
int done = 0;
int ind = 0;
int err = 0;
char s[10];
if (argc != 3)
error("Usage: getopts optstring var");
if (shellparam.optnext == NULL) {
shellparam.optnext = shellparam.p;
shellparam.optptr = NULL;
}
if ((p = shellparam.optptr) == NULL || *p == '\0') {
p = *shellparam.optnext;
if ((p = *optptr) == NULL || *p == '\0') {
/* Current word is done, advance */
if (*optnext == NULL)
return 1;
p = **optnext;
if (p == NULL || *p != '-' || *++p == '\0') {
atend:
fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1);
setvar("OPTIND", s, 0);
shellparam.optnext = NULL;
return 1;
ind = *optnext - optfirst + 1;
*optnext = NULL;
p = NULL;
done = 1;
goto out;
}
shellparam.optnext++;
(*optnext)++;
if (p[0] == '-' && p[1] == '\0') /* check for "--" */
goto atend;
}
c = *p++;
for (q = argv[1] ; *q != c ; ) {
for (q = optstr; *q != c; ) {
if (*q == '\0') {
out1fmt("Illegal option -%c\n", c);
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
}
else {
out1fmt("Illegal option -%c\n", c);
(void) unsetvar("OPTARG");
}
c = '?';
goto out;
goto bad;
}
if (*++q == ':')
q++;
}
if (*++q == ':') {
if (*p == '\0') {
if ((p = *shellparam.optnext) == NULL) {
out1fmt("No arg for -%c option\n", c);
c = '?';
goto out;
if (*p == '\0' && (p = **optnext) == NULL) {
if (optstr[0] == ':') {
s[0] = c;
s[1] = '\0';
err |= setvarsafe("OPTARG", s, 0);
c = ':';
}
shellparam.optnext++;
else {
out1fmt("No arg for -%c option\n", c);
(void) unsetvar("OPTARG");
c = '?';
}
goto bad;
}
setvar("OPTARG", p, 0);
p = "";
if (p == **optnext)
(*optnext)++;
setvarsafe("OPTARG", p, 0);
p = NULL;
}
else
setvarsafe("OPTARG", "", 0);
ind = *optnext - optfirst + 1;
goto out;
bad:
ind = 1;
*optnext = NULL;
p = NULL;
out:
shellparam.optptr = p;
*optptr = p;
fmtstr(s, sizeof(s), "%d", ind);
err |= setvarsafe("OPTIND", s, VNOFUNC);
s[0] = c;
s[1] = '\0';
setvar(argv[2], s, 0);
fmtstr(s, 10, "%d", shellparam.optnext - shellparam.p + 1);
setvar("OPTIND", s, 0);
return 0;
err |= setvarsafe(optvar, s, 0);
if (err) {
*optnext = NULL;
*optptr = NULL;
flushall();
exraise(EXERROR);
}
return done;
}
/*
* XXX - should get rid of. have all builtins use getopt(3). the
* library getopt must have the BSD extension static variable "optreset"
* otherwise it can't be used within the shell safely.
*
* Standard option processing (a la getopt) for builtin routines. The
* only argument that is passed to nextopt is the option string; the
* other arguments are unnecessary. It return the character, or '\0' on
@@ -365,10 +511,9 @@ out:
*/
int
nextopt(optstring)
char *optstring;
{
register char *p, *q;
nextopt(char *optstring)
{
char *p, *q;
char c;
if ((p = optptr) == NULL || *p == '\0') {
@@ -389,9 +534,13 @@ nextopt(optstring)
if (*++q == ':') {
if (*p == '\0' && (p = *argptr++) == NULL)
error("No arg for -%c option", c);
optarg = p;
shoptarg = p;
p = NULL;
}
optptr = p;
return c;
}
/*
* $PchId: options.c,v 1.6 2006/05/29 13:09:12 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,38 +29,71 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)options.h 5.1 (Berkeley) 3/7/91
* @(#)options.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/options.h,v 1.13 2004/04/06 20:06:51 markm Exp $
*/
struct shparam {
int nparam; /* number of positional parameters (without $0) */
char malloc; /* true if parameter list dynamicly allocated */
int nparam; /* # of positional parameters (without $0) */
unsigned char malloc; /* if parameter list dynamically allocated */
unsigned char reset; /* if getopts has been reset */
char **p; /* parameter list */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
char **optnext; /* next parameter to be processed by getopts */
char *optptr; /* used by getopts */
};
#define eflag optval[0]
#define fflag optval[1]
#define Iflag optval[2]
#define iflag optval[3]
#define jflag optval[4]
#define nflag optval[5]
#define sflag optval[6]
#define xflag optval[7]
#define zflag optval[8]
#define vflag optval[9]
#define eflag optlist[0].val
#define fflag optlist[1].val
#define Iflag optlist[2].val
#define iflag optlist[3].val
#define mflag optlist[4].val
#define nflag optlist[5].val
#define sflag optlist[6].val
#define xflag optlist[7].val
#define vflag optlist[8].val
#define Vflag optlist[9].val
#define Eflag optlist[10].val
#define Cflag optlist[11].val
#define aflag optlist[12].val
#define bflag optlist[13].val
#define uflag optlist[14].val
#define privileged optlist[15].val
#define Tflag optlist[16].val
#define Pflag optlist[17].val
#define NOPTS 10
#define NOPTS 18
struct optent {
const char *name;
const char letter;
char val;
};
#ifdef DEFINE_OPTIONS
const char optchar[NOPTS+1] = "efIijnsxzv"; /* shell flags */
char optval[NOPTS+1]; /* values of option flags */
struct optent optlist[NOPTS] = {
{ "errexit", 'e', 0 },
{ "noglob", 'f', 0 },
{ "ignoreeof", 'I', 0 },
{ "interactive",'i', 0 },
{ "monitor", 'm', 0 },
{ "noexec", 'n', 0 },
{ "stdin", 's', 0 },
{ "xtrace", 'x', 0 },
{ "verbose", 'v', 0 },
{ "vi", 'V', 0 },
{ "emacs", 'E', 0 },
{ "noclobber", 'C', 0 },
{ "allexport", 'a', 0 },
{ "notify", 'b', 0 },
{ "nounset", 'u', 0 },
{ "privileged", 'p', 0 },
{ "trapsasync", 'T', 0 },
{ "physical", 'P', 0 },
};
#else
extern const char optchar[NOPTS+1];
extern char optval[NOPTS+1];
extern struct optent optlist[NOPTS];
#endif
@@ -72,19 +101,20 @@ extern char *minusc; /* argument to -c option */
extern char *arg0; /* $0 */
extern struct shparam shellparam; /* $@ */
extern char **argptr; /* argument list for builtin commands */
extern char *optarg; /* set by nextopt */
extern char *shoptarg; /* set by nextopt */
extern char *optptr; /* used by nextopt */
extern int editable; /* isatty(0) && isatty(1) */
extern int editable; /* isatty(0) && isatty(1) */
#ifdef __STDC__
void procargs(int, char **);
void optschanged(void);
void setparam(char **);
void freeparam(struct shparam *);
int shiftcmd(int, char **);
int setcmd(int, char **);
int getoptscmd(int, char **);
int nextopt(char *);
#else
void procargs();
void setparam();
void freeparam();
int nextopt();
#endif
void getoptsreset(const char *);
/*
* $PchId: options.h,v 1.5 2006/05/29 13:08:45 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,7 +31,7 @@
*/
#ifndef lint
static char sccsid[] = "@(#)output.c 5.1 (Berkeley) 3/7/91";
static char sccsid[] = "@(#)output.c 8.1 (Berkeley) 5/31/93";
#endif /* not lint */
/*
@@ -55,12 +51,16 @@ static char sccsid[] = "@(#)output.c 5.1 (Berkeley) 3/7/91";
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "var.h"
#ifdef __STDC__
#include "stdarg.h"
#else
#include <varargs.h>
#endif
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#define OUTBUFSIZ BUFSIZ
@@ -115,27 +115,63 @@ open_mem(block, length, file)
void
out1str(p)
char *p;
const char *p;
{
outstr(p, out1);
}
void
out1qstr(const char *p)
{
outqstr(p, out1);
}
void
out2str(p)
char *p;
{
out2str(const char *p)
{
outstr(p, out2);
}
void
outstr(p, file)
register char *p;
register const char *p;
register struct output *file;
{
while (*p)
outc(*p++, file);
if (file == out2)
flushout(file);
}
/* Like outstr(), but quote for re-input into the shell. */
void
outqstr(const char *p, struct output *file)
{
char ch;
if (p[strcspn(p, "|&;<>()$`\\\"'")] == '\0' && (!ifsset() ||
p[strcspn(p, ifsval())] == '\0')) {
outstr(p, file);
return;
}
out1c('\'');
while ((ch = *p++) != '\0') {
switch (ch) {
case '\'':
/*
* Can't quote single quotes inside single quotes;
* close them, write escaped single quote, open again.
*/
outstr("'\\''", file);
break;
default:
outc(ch, file);
}
}
out1c('\'');
}
@@ -208,7 +244,8 @@ freestdout() {
#ifdef __STDC__
void
outfmt(struct output *file, char *fmt, ...) {
outfmt(struct output *file, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -218,7 +255,8 @@ outfmt(struct output *file, char *fmt, ...) {
void
out1fmt(char *fmt, ...) {
out1fmt(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -226,9 +264,20 @@ out1fmt(char *fmt, ...) {
va_end(ap);
}
void
dprintf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(char *outbuf, int length, char *fmt, ...) {
fmtstr(char *outbuf, int length, const char *fmt, ...)
{
va_list ap;
struct output strout;
@@ -275,6 +324,19 @@ out1fmt(va_alist)
va_end(ap);
}
void
dprintf(va_alist)
va_dcl
{
va_list ap;
char *fmt;
va_start(ap);
fmt = va_arg(ap, char *);
doformat(out2, fmt, ap);
va_end(ap);
flushout(out2);
}
void
fmtstr(va_alist)
@@ -325,11 +387,8 @@ static const char digit[17] = "0123456789ABCDEF";
void
doformat(dest, f, ap)
register struct output *dest;
register char *f; /* format string */
va_list ap;
{
doformat(struct output *dest, const char *f, va_list ap)
{
register char c;
char temp[TEMPSIZE];
int flushleft;
@@ -517,15 +576,6 @@ xwrite(fd, buf, nbytes)
}
}
/*
* Version of ioctl that retries after a signal is caught.
* $PchId: output.c,v 1.6 2006/05/22 12:46:03 philip Exp $
*/
int
xioctl(fd, request, arg) {
int i;
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR);
return i;
}

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,11 +29,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)output.h 5.1 (Berkeley) 3/7/91
* @(#)output.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/output.h,v 1.13 2004/04/06 20:06:51 markm Exp $
*/
#ifndef OUTPUT_INCL
#include <stdarg.h>
struct output {
char *nextc;
int nleft;
@@ -53,38 +52,27 @@ extern struct output memout;
extern struct output *out1;
extern struct output *out2;
#ifndef __printflike
#define __printflike(a,b)
#endif
#ifdef __STDC__
void outstr(char *, struct output *);
void out1str(char *);
void out2str(char *);
void outfmt(struct output *, char *, ...);
void out1fmt(char *, ...);
void fmtstr(char *, int, char *, ...);
/* void doformat(struct output *, char *, va_list); */
void doformat();
void open_mem(char *, int, struct output *);
void out1str(const char *);
void out1qstr(const char *);
void out2str(const char *);
void out2qstr(const char *);
void outstr(const char *, struct output *);
void outqstr(const char *, struct output *);
void emptyoutbuf(struct output *);
void flushall(void);
void flushout(struct output *);
void freestdout(void);
void outfmt(struct output *, const char *, ...) __printflike(2, 3);
void out1fmt(const char *, ...) __printflike(1, 2);
void dprintf(const char *, ...) __printflike(1, 2);
void fmtstr(char *, int, const char *, ...) __printflike(3, 4);
void doformat(struct output *, const char *, va_list) __printflike(2, 0);
int xwrite(int, char *, int);
int xioctl(int, int, int);
#else
void outstr();
void out1str();
void out2str();
void outfmt();
void out1fmt();
void fmtstr();
/* void doformat(); */
void doformat();
void emptyoutbuf();
void flushall();
void flushout();
void freestdout();
int xwrite();
int xioctl();
#endif
#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c)))
#define out1c(c) outc(c, out1);
@@ -92,3 +80,7 @@ int xioctl();
#define OUTPUT_INCL
#endif
/*
* $PchId: output.h,v 1.5 2006/05/23 12:04:54 philip Exp $
*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)parser.h 5.1 (Berkeley) 3/7/91
* @(#)parser.h 8.3 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/parser.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
/* control characters in argument strings */
@@ -42,18 +39,27 @@
#define CTLENDVAR '\203'
#define CTLBACKQ '\204'
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */
/* CTLBACKQ | CTLQUOTE == '\205' */
#define CTLARI '\206'
#define CTLENDARI '\207'
#define CTLQUOTEMARK '\210'
/* variable substitution byte (follows CTLVAR) */
#define VSTYPE 07 /* type of variable substitution */
#define VSNUL 040 /* colon--treat the empty string as unset */
#define VSQUOTE 0100 /* inside double quotes--suppress splitting */
#define VSTYPE 0x0f /* type of variable substitution */
#define VSNUL 0x10 /* colon--treat the empty string as unset */
#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */
/* values of VSTYPE field */
#define VSNORMAL 1 /* normal variable: $var or ${var} */
#define VSMINUS 2 /* ${var-text} */
#define VSPLUS 3 /* ${var+text} */
#define VSQUESTION 4 /* ${var?message} */
#define VSASSIGN 5 /* ${var=text} */
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */
#define VSMINUS 0x2 /* ${var-text} */
#define VSPLUS 0x3 /* ${var+text} */
#define VSQUESTION 0x4 /* ${var?message} */
#define VSASSIGN 0x5 /* ${var=text} */
#define VSTRIMLEFT 0x6 /* ${var#pattern} */
#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */
#define VSLENGTH 0xa /* ${#var} */
/*
@@ -63,12 +69,14 @@
*/
extern int tokpushback;
#define NEOF ((union node *)&tokpushback)
extern int whichprompt; /* 1 == PS1, 2 == PS2 */
#ifdef __STDC__
union node *parsecmd(int);
void fixredir(union node *, const char *, int);
int goodname(char *);
#else
union node *parsecmd();
int goodname();
#endif
char *getprompt(void *);
/*
* $PchId: parser.h,v 1.3 2006/03/29 14:33:35 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,8 +31,23 @@
*/
#ifndef lint
static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
#if 0
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/redir.c,v 1.26 2004/04/06 20:06:51 markm Exp $");
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
/*
* Code for dealing with input/output redirection.
@@ -47,15 +58,10 @@ static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
#include "jobs.h"
#include "expand.h"
#include "redir.h"
#include "eval.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include <sys/types.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <limits.h>
#include "options.h"
#define EMPTY -2 /* marks an unused slot in redirtab */
@@ -65,25 +71,21 @@ static char sccsid[] = "@(#)redir.c 5.1 (Berkeley) 3/7/91";
MKINIT
struct redirtab {
struct redirtab *next;
short renamed[10];
int renamed[10];
};
MKINIT struct redirtab *redirlist;
/* We keep track of whether or not fd0 has been redirected. This is for
background commands, where we want to redirect fd0 to /dev/null only
if it hasn't already been redirected. */
int fd0_redirected = 0;
/*
* We keep track of whether or not fd0 has been redirected. This is for
* background commands, where we want to redirect fd0 to /dev/null only
* if it hasn't already been redirected.
*/
STATIC int fd0_redirected = 0;
#ifdef __STDC__
STATIC void openredirect(union node *, char *);
STATIC void openredirect(union node *, char[10 ]);
STATIC int openhere(union node *);
#else
STATIC void openredirect();
STATIC int openhere();
#endif
/*
@@ -95,15 +97,14 @@ STATIC int openhere();
*/
void
redirect(redir, flags)
union node *redir;
int flags;
{
redirect(union node *redir, int flags)
{
union node *n;
struct redirtab *sv;
struct redirtab *sv = NULL;
int i;
int fd;
char memory[10]; /* file descriptors to write to memory */
int try;
char memory[10]; /* file descriptors to write to memory */
for (i = 10 ; --i >= 0 ; )
memory[i] = 0;
@@ -117,21 +118,38 @@ redirect(redir, flags)
}
for (n = redir ; n ; n = n->nfile.next) {
fd = n->nfile.fd;
try = 0;
if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) &&
n->ndup.dupfd == fd)
continue; /* redirect from/to same file descriptor */
if ((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) {
INTOFF;
if ((i = copyfd(fd, 10)) != EMPTY) {
again:
if ((i = fcntl(fd, F_DUPFD, 10)) == -1) {
switch (errno) {
case EBADF:
if (!try) {
openredirect(n, memory);
try++;
goto again;
}
/* FALLTHROUGH*/
default:
INTON;
error("%d: %s", fd, strerror(errno));
break;
}
}
if (!try) {
sv->renamed[fd] = i;
close(fd);
}
INTON;
if (i == EMPTY)
error("Out of file descriptors");
} else {
close(fd);
}
if (fd == 0)
fd0_redirected++;
openredirect(n, memory);
if (!try)
openredirect(n, memory);
}
if (memory[1])
out1 = &memout;
@@ -141,16 +159,15 @@ redirect(redir, flags)
STATIC void
openredirect(redir, memory)
union node *redir;
char memory[10];
{
openredirect(union node *redir, char memory[10])
{
struct stat sb;
int fd = redir->nfile.fd;
char *fname;
int f;
/* Assume redirection succeeds. */
exitstatus = 0;
{ extern int exitstatus; exitstatus = 0; }
/*
* We suppress interrupts so that we won't leave open file
@@ -163,34 +180,35 @@ openredirect(redir, memory)
case NFROM:
fname = redir->nfile.expfname;
if ((f = open(fname, O_RDONLY)) < 0)
error("cannot open %s: %s", fname, errmsg(errno, E_OPEN));
error("cannot open %s: %s", fname, strerror(errno));
movefd:
if (f != fd) {
copyfd(f, fd);
dup2(f, fd);
close(f);
}
break;
case NFROMTO:
fname = redir->nfile.expfname;
if ((f = open(fname, O_RDWR|O_CREAT, 0666)) < 0)
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NTO:
fname = redir->nfile.expfname;
#ifdef O_CREAT
if (Cflag && stat(fname, &sb) != -1 && S_ISREG(sb.st_mode))
error("cannot create %s: %s", fname,
strerror(EEXIST));
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#endif
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NCLOBBER:
fname = redir->nfile.expfname;
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0)
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NAPPEND:
fname = redir->nfile.expfname;
#ifdef O_APPEND
if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
#else
if ((f = open(fname, O_WRONLY)) < 0
&& (f = creat(fname, 0666)) < 0)
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT));
lseek(f, 0L, 2);
#endif
error("cannot create %s: %s", fname, strerror(errno));
goto movefd;
case NTOFD:
case NFROMFD:
@@ -198,7 +216,9 @@ movefd:
if (memory[redir->ndup.dupfd])
memory[fd] = 1;
else
copyfd(redir->ndup.dupfd, fd);
dup2(redir->ndup.dupfd, fd);
} else {
close(fd);
}
break;
case NHERE:
@@ -219,14 +239,13 @@ movefd:
*/
STATIC int
openhere(redir)
union node *redir;
{
openhere(union node *redir)
{
int pip[2];
int len;
int len = 0;
if (pipe(pip) < 0)
error("Pipe call failed");
error("Pipe call failed: %s", strerror(errno));
if (redir->type == NHERE) {
len = strlen(redir->nhere.doc->narg.text);
if (len <= PIPESIZE) {
@@ -239,9 +258,7 @@ openhere(redir)
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
signal(SIGHUP, SIG_IGN);
#ifdef SIGTSTP
signal(SIGTSTP, SIG_IGN);
#endif
signal(SIGPIPE, SIG_DFL);
if (redir->type == NHERE)
xwrite(pip[1], redir->nhere.doc->narg.text, len);
@@ -261,18 +278,20 @@ out:
*/
void
popredir() {
register struct redirtab *rp = redirlist;
popredir(void)
{
struct redirtab *rp = redirlist;
int i;
for (i = 0 ; i < 10 ; i++) {
if (rp->renamed[i] != EMPTY) {
if (i == 0)
fd0_redirected--;
close(i);
if (i == 0)
fd0_redirected--;
if (rp->renamed[i] >= 0) {
copyfd(rp->renamed[i], i);
dup2(rp->renamed[i], i);
close(rp->renamed[i]);
} else {
close(i);
}
}
}
@@ -282,8 +301,6 @@ popredir() {
INTON;
}
/*
* Undo all redirections. Called on error or interrupt.
*/
@@ -303,14 +320,21 @@ SHELLPROC {
#endif
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p(void)
{
return fd0_redirected != 0;
}
/*
* Discard all saved file descriptors.
*/
void
clearredir() {
register struct redirtab *rp;
clearredir(void)
{
struct redirtab *rp;
int i;
for (rp = redirlist ; rp ; rp = rp->next) {
@@ -323,48 +347,6 @@ clearredir() {
}
}
/*
* Copy a file descriptor, like the F_DUPFD option of fcntl. Returns -1
* if the source file descriptor is closed, EMPTY if there are no unused
* file descriptors left.
* $PchId: redir.c,v 1.5 2006/05/22 12:27:37 philip Exp $
*/
int
copyfd(from, to) {
#ifdef F_DUPFD
int newfd;
newfd = fcntl(from, F_DUPFD, to);
if (newfd < 0 && errno == EMFILE)
return EMPTY;
return newfd;
#else
char toclose[32];
int i;
int newfd;
int e;
for (i = 0 ; i < to ; i++)
toclose[i] = 0;
INTOFF;
while ((newfd = dup(from)) >= 0 && newfd < to)
toclose[newfd] = 1;
e = errno;
for (i = 0 ; i < to ; i++) {
if (toclose[i])
close(i);
}
INTON;
if (newfd < 0 && e == EMFILE)
return EMPTY;
return newfd;
#endif
}
/* Return true if fd 0 has already been redirected at least once. */
int
fd0_redirected_p () {
return fd0_redirected != 0;
}

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,24 +29,21 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)redir.h 5.1 (Berkeley) 3/7/91
* @(#)redir.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/redir.h,v 1.10 2004/04/06 20:06:51 markm Exp $
*/
/* flags passed to redirect */
#define REDIR_PUSH 01 /* save previous values of file descriptors */
#define REDIR_BACKQ 02 /* save the command output in memory */
#ifdef __STDC__
union node;
void redirect(union node *, int);
void popredir(void);
void clearredir(void);
int copyfd(int, int);
int fd0_redirected_p(void);
#else
void redirect();
void popredir();
void clearredir();
int copyfd();
int fd0_redirected_p();
#endif
void clearredir(void);
/*
* $PchId: redir.h,v 1.3 2006/03/29 14:13:34 philip Exp $
*/

463
commands/ash/setmode.c Normal file
View File

@@ -0,0 +1,463 @@
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Dave Borman at Cray Research, Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stddef.h>
#include <stdlib.h>
#ifdef SETMODE_DEBUG
#include <stdio.h>
#endif
#include "shell.h"
#ifndef S_ISTXT
#define S_ISTXT S_ISVTX
#endif
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */
typedef struct bitcmd {
char cmd;
char cmd2;
mode_t bits;
} BITCMD;
#define CMD2_CLR 0x01
#define CMD2_SET 0x02
#define CMD2_GBITS 0x04
#define CMD2_OBITS 0x08
#define CMD2_UBITS 0x10
static BITCMD *addcmd (BITCMD *, int, int, int, unsigned int);
static int compress_mode (BITCMD *);
#ifdef SETMODE_DEBUG
static void dumpmode __P((BITCMD *));
#endif
/*
* Given the old mode and an array of bitcmd structures, apply the operations
* described in the bitcmd structures to the old mode, and return the new mode.
* Note that there is no '=' command; a strict assignment is just a '-' (clear
* bits) followed by a '+' (set bits).
*/
mode_t
getmode(bbox, omode)
void *bbox;
mode_t omode;
{
register BITCMD *set;
register mode_t clrval, newmode, value;
set = (BITCMD *)bbox;
newmode = omode;
for (value = 0;; set++)
switch(set->cmd) {
/*
* When copying the user, group or other bits around, we "know"
* where the bits are in the mode so that we can do shifts to
* copy them around. If we don't use shifts, it gets real
* grundgy with lots of single bit checks and bit sets.
*/
case 'u':
value = (newmode & S_IRWXU) >> 6;
goto common;
case 'g':
value = (newmode & S_IRWXG) >> 3;
goto common;
case 'o':
value = newmode & S_IRWXO;
common: if (set->cmd2 & CMD2_CLR) {
clrval =
(set->cmd2 & CMD2_SET) ? S_IRWXO : value;
if (set->cmd2 & CMD2_UBITS)
newmode &= ~((clrval<<6) & set->bits);
if (set->cmd2 & CMD2_GBITS)
newmode &= ~((clrval<<3) & set->bits);
if (set->cmd2 & CMD2_OBITS)
newmode &= ~(clrval & set->bits);
}
if (set->cmd2 & CMD2_SET) {
if (set->cmd2 & CMD2_UBITS)
newmode |= (value<<6) & set->bits;
if (set->cmd2 & CMD2_GBITS)
newmode |= (value<<3) & set->bits;
if (set->cmd2 & CMD2_OBITS)
newmode |= value & set->bits;
}
break;
case '+':
newmode |= set->bits;
break;
case '-':
newmode &= ~set->bits;
break;
case 'X':
if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH))
newmode |= set->bits;
break;
case '\0':
default:
#ifdef SETMODE_DEBUG
(void)printf("getmode:%04o -> %04o\n", omode, newmode);
#endif
return (newmode);
}
}
#define ADDCMD(a, b, c, d) \
if (set >= endset) { \
register BITCMD *newset; \
setlen += SET_LEN_INCR; \
newset = realloc(saveset, sizeof(BITCMD) * setlen); \
if (!saveset) \
return (NULL); \
set = newset + (set - saveset); \
saveset = newset; \
endset = newset + (setlen - 2); \
} \
set = addcmd(set, (a), (b), (c), (d))
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO)
void *
setmode(p)
register char *p;
{
register int perm, who;
register char op;
BITCMD *set, *saveset, *endset;
sigset_t sigset, sigoset;
mode_t mask;
int equalopdone, permXbits, setlen;
if (!*p)
return (NULL);
/*
* Get a copy of the mask for the permissions that are mask relative.
* Flip the bits, we want what's not set. Since it's possible that
* the caller is opening files inside a signal handler, protect them
* as best we can.
*/
sigfillset(&sigset);
(void)sigprocmask(SIG_BLOCK, &sigset, &sigoset);
(void)umask(mask = umask(0));
mask = ~mask;
(void)sigprocmask(SIG_SETMASK, &sigoset, NULL);
setlen = SET_LEN + 2;
if ((set = malloc((unsigned int)(sizeof(BITCMD) * setlen))) == NULL)
return (NULL);
saveset = set;
endset = set + (setlen - 2);
/*
* If an absolute number, get it and return; disallow non-octal digits
* or illegal bits.
*/
if (isdigit(*p)) {
perm = (mode_t)strtol(p, NULL, 8);
if (perm & ~(STANDARD_BITS|S_ISTXT)) {
free(saveset);
return (NULL);
}
while (*++p)
if (*p < '0' || *p > '7') {
free(saveset);
return (NULL);
}
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask);
return (saveset);
}
/*
* Build list of structures to set/clear/copy bits as described by
* each clause of the symbolic mode.
*/
for (;;) {
/* First, find out which bits might be modified. */
for (who = 0;; ++p) {
switch (*p) {
case 'a':
who |= STANDARD_BITS;
break;
case 'u':
who |= S_ISUID|S_IRWXU;
break;
case 'g':
who |= S_ISGID|S_IRWXG;
break;
case 'o':
who |= S_IRWXO;
break;
default:
goto getop;
}
}
getop: if ((op = *p++) != '+' && op != '-' && op != '=') {
free(saveset);
return (NULL);
}
if (op == '=')
equalopdone = 0;
who &= ~S_ISTXT;
for (perm = 0, permXbits = 0;; ++p) {
switch (*p) {
case 'r':
perm |= S_IRUSR|S_IRGRP|S_IROTH;
break;
case 's':
/* If only "other" bits ignore set-id. */
if (who & ~S_IRWXO)
perm |= S_ISUID|S_ISGID;
break;
case 't':
/* If only "other" bits ignore sticky. */
if (who & ~S_IRWXO) {
who |= S_ISTXT;
perm |= S_ISTXT;
}
break;
case 'w':
perm |= S_IWUSR|S_IWGRP|S_IWOTH;
break;
case 'X':
permXbits = S_IXUSR|S_IXGRP|S_IXOTH;
break;
case 'x':
perm |= S_IXUSR|S_IXGRP|S_IXOTH;
break;
case 'u':
case 'g':
case 'o':
/*
* When ever we hit 'u', 'g', or 'o', we have
* to flush out any partial mode that we have,
* and then do the copying of the mode bits.
*/
if (perm) {
ADDCMD(op, who, perm, mask);
perm = 0;
}
if (op == '=')
equalopdone = 1;
if (op == '+' && permXbits) {
ADDCMD('X', who, permXbits, mask);
permXbits = 0;
}
ADDCMD(*p, who, op, mask);
break;
default:
/*
* Add any permissions that we haven't already
* done.
*/
if (perm || (op == '=' && !equalopdone)) {
if (op == '=')
equalopdone = 1;
ADDCMD(op, who, perm, mask);
perm = 0;
}
if (permXbits) {
ADDCMD('X', who, permXbits, mask);
permXbits = 0;
}
goto apply;
}
}
apply: if (!*p)
break;
if (*p != ',')
goto getop;
++p;
}
set->cmd = 0;
#ifdef SETMODE_DEBUG
(void)printf("Before compress_mode()\n");
dumpmode(saveset);
#endif
compress_mode(saveset);
#ifdef SETMODE_DEBUG
(void)printf("After compress_mode()\n");
dumpmode(saveset);
#endif
return (saveset);
}
static BITCMD *
addcmd(set, op, who, oparg, mask)
BITCMD *set;
register int oparg, who;
register int op;
unsigned int mask;
{
switch (op) {
case '=':
set->cmd = '-';
set->bits = who ? who : STANDARD_BITS;
set++;
op = '+';
/* FALLTHROUGH */
case '+':
case '-':
case 'X':
set->cmd = op;
set->bits = (who ? who : mask) & oparg;
break;
case 'u':
case 'g':
case 'o':
set->cmd = op;
if (who) {
set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) |
((who & S_IRGRP) ? CMD2_GBITS : 0) |
((who & S_IROTH) ? CMD2_OBITS : 0);
set->bits = ~0;
} else {
set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS;
set->bits = mask;
}
if (oparg == '+')
set->cmd2 |= CMD2_SET;
else if (oparg == '-')
set->cmd2 |= CMD2_CLR;
else if (oparg == '=')
set->cmd2 |= CMD2_SET|CMD2_CLR;
break;
}
return (set + 1);
}
#ifdef SETMODE_DEBUG
static void
dumpmode(set)
register BITCMD *set;
{
for (; set->cmd; ++set)
(void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n",
set->cmd, set->bits, set->cmd2 ? " cmd2:" : "",
set->cmd2 & CMD2_CLR ? " CLR" : "",
set->cmd2 & CMD2_SET ? " SET" : "",
set->cmd2 & CMD2_UBITS ? " UBITS" : "",
set->cmd2 & CMD2_GBITS ? " GBITS" : "",
set->cmd2 & CMD2_OBITS ? " OBITS" : "");
}
#endif
/*
* Given an array of bitcmd structures, compress by compacting consecutive
* '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u',
* 'g' and 'o' commands continue to be separate. They could probably be
* compacted, but it's not worth the effort.
*/
static int
compress_mode(set)
register BITCMD *set;
{
register BITCMD *nset;
register int setbits, clrbits, Xbits, op;
for (nset = set;;) {
/* Copy over any 'u', 'g' and 'o' commands. */
while ((op = nset->cmd) != '+' && op != '-' && op != 'X') {
*set++ = *nset++;
if (!op)
return;
}
for (setbits = clrbits = Xbits = 0;; nset++) {
if ((op = nset->cmd) == '-') {
clrbits |= nset->bits;
setbits &= ~nset->bits;
Xbits &= ~nset->bits;
} else if (op == '+') {
setbits |= nset->bits;
clrbits &= ~nset->bits;
Xbits &= ~nset->bits;
} else if (op == 'X')
Xbits |= nset->bits & ~setbits;
else
break;
}
if (clrbits) {
set->cmd = '-';
set->cmd2 = 0;
set->bits = clrbits;
set++;
}
if (setbits) {
set->cmd = '+';
set->cmd2 = 0;
set->bits = setbits;
set++;
}
if (Xbits) {
set->cmd = 'X';
set->cmd2 = 0;
set->bits = Xbits;
set++;
}
}
}
/*
* $PchId: setmode.c,v 1.3 2006/05/23 11:57:34 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,19 +29,17 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)shell.h 5.4 (Berkeley) 4/12/91
* @(#)shell.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/shell.h,v 1.17 2004/04/06 20:06:51 markm Exp $
*/
#include <sys/types.h> /* for mode_t */
/*
* The follow should be set to reflect the type of system you have:
* JOBS -> 1 if you have Berkeley job control, 0 otherwise.
* SYMLINKS -> 1 if your system includes symbolic links, 0 otherwise.
* DIRENT -> 1 if your system has the SVR3 directory(3X) routines.
* UDIR -> 1 if you want the shell to simulate the /u directory.
* TILDE -> 1 if you want the shell to expand ~logname.
* USEGETPW -> 1 if getpwnam() must be used to look up a name.
* ATTY -> 1 to include code for atty(1).
* SHORTNAMES -> 1 if your linker cannot handle long names.
* READLINE -> 1 if line editing by readline() should be enabled.
* define BSD if you are running 4.2 BSD or later.
* define SYSV if you are running under System V.
@@ -56,52 +50,47 @@
* a quit signal will generate a core dump.
*/
#ifndef JOBS
#define JOBS 1
#endif
#ifndef BSD
#define BSD 1
#endif
#ifndef DEBUG
#define DEBUG 0
#endif
#define POSIX 1
#define JOBS 0
/* Set SYMLINKS to 0 by request of Giovanni Falzoni, who wrote the
* symlink patches for Minix; email to minix-devel-l of thu 3 nov.
/*
* Type of used arithmetics. SUSv3 requires us to have at least signed long.
*/
typedef long arith_t;
#define ARITH_FORMAT_STR "%ld"
#define atoarith_t(arg) strtol(arg, NULL, 0)
#define strtoarith_t(nptr, endptr, base) strtol(nptr, endptr, base)
#if 0
#define SYMLINKS defined(S_ISLNK)
#else
#define SYMLINKS 0
#endif
#define DIRENT 1
#define UDIR 0
#define TILDE 1
#define USEGETPW 0
#define ATTY 0
#define READLINE 1
#define HASHBANG 0
/* #define BSD */
#define POSIX 1
#define DEBUG 0
#ifdef __STDC__
typedef void *pointer;
#ifndef NULL
#define NULL (void *)0
#endif
#else /* not __STDC__ */
typedef char *pointer;
#ifndef NULL
#define NULL 0
#endif
#endif /* not __STDC__ */
#define STATIC /* empty */
#define MKINIT /* empty */
#include <sys/cdefs.h>
#include <sys/types.h>
#define STATIC static
#define MKINIT /* empty */
extern char nullstr[1]; /* null string */
#if DEBUG
#define TRACE(param) trace param
#define TRACE(param) sh_trace param
#else
#define TRACE(param)
#endif
#ifdef __minix
#define __unused
typedef long quad_t; /* XXX */
typedef unsigned long u_quad_t; /* XXX */
#endif
mode_t getmode(void *, int /* mode_t */);
void *setmode(char *);
/*
* $PchId: shell.h,v 1.7 2006/05/22 12:47:00 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,38 +31,54 @@
*/
#ifndef lint
static char sccsid[] = "@(#)show.c 5.2 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/show.c,v 1.21 2004/04/06 20:06:51 markm Exp $");
*/
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>
#include "shell.h"
#include "parser.h"
#include "nodes.h"
#include "mystring.h"
#include "show.h"
#if DEBUG
static shtree(), shcmd(), sharg(), indent();
static void trputc(int c);
static void shtree(union node *, int, char *, FILE*);
static void shcmd(union node *, FILE *);
static void sharg(union node *, FILE *);
static void indent(int, char *, FILE *);
static void trstring(char *);
static void showtree(union node *n);
showtree(n)
union node *n;
{
static void
showtree(union node *n)
{
trputs("showtree called\n");
shtree(n, 1, NULL, stdout);
}
static
shtree(n, ind, pfx, fp)
union node *n;
char *pfx;
FILE *fp;
{
static void
shtree(union node *n, int ind, char *pfx, FILE *fp)
{
struct nodelist *lp;
char *s;
if (n == NULL)
return;
indent(ind, pfx, fp);
switch(n->type) {
case NSEMI:
@@ -109,11 +121,9 @@ binop:
static
shcmd(cmd, fp)
union node *cmd;
FILE *fp;
{
static void
shcmd(union node *cmd, FILE *fp)
{
union node *np;
int first;
char *s;
@@ -133,14 +143,20 @@ shcmd(cmd, fp)
case NTO: s = ">"; dftfd = 1; break;
case NAPPEND: s = ">>"; dftfd = 1; break;
case NTOFD: s = ">&"; dftfd = 1; break;
case NCLOBBER: s = ">|"; dftfd = 1; break;
case NFROM: s = "<"; dftfd = 0; break;
case NFROMTO: s = "<>"; dftfd = 0; break;
case NFROMFD: s = "<&"; dftfd = 0; break;
default: s = "*error*"; dftfd = 0; break;
}
if (np->nfile.fd != dftfd)
fprintf(fp, "%d", np->nfile.fd);
fputs(s, fp);
if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
fprintf(fp, "%d", np->ndup.dupfd);
if (np->ndup.dupfd >= 0)
fprintf(fp, "%d", np->ndup.dupfd);
else
fprintf(fp, "-");
} else {
sharg(np->nfile.fname, fp);
}
@@ -150,11 +166,9 @@ shcmd(cmd, fp)
static
sharg(arg, fp)
union node *arg;
FILE *fp;
{
static void
sharg(union node *arg, FILE *fp)
{
char *p;
struct nodelist *bqlist;
int subtype;
@@ -174,10 +188,15 @@ sharg(arg, fp)
putc('$', fp);
putc('{', fp);
subtype = *++p;
if (subtype == VSLENGTH)
putc('#', fp);
while (*p != '=')
putc(*p++, fp);
if (subtype & VSNUL)
putc(':', fp);
switch (subtype & VSTYPE) {
case VSNORMAL:
putc('}', fp);
@@ -194,6 +213,22 @@ sharg(arg, fp)
case VSASSIGN:
putc('=', fp);
break;
case VSTRIMLEFT:
putc('#', fp);
break;
case VSTRIMLEFTMAX:
putc('#', fp);
putc('#', fp);
break;
case VSTRIMRIGHT:
putc('%', fp);
break;
case VSTRIMRIGHTMAX:
putc('%', fp);
putc('%', fp);
break;
case VSLENGTH:
break;
default:
printf("<subtype %d>", subtype);
}
@@ -216,11 +251,9 @@ sharg(arg, fp)
}
static
indent(amount, pfx, fp)
char *pfx;
FILE *fp;
{
static void
indent(int amount, char *pfx, FILE *fp)
{
int i;
for (i = 0 ; i < amount ; i++) {
@@ -229,8 +262,6 @@ indent(amount, pfx, fp)
putc('\t', fp);
}
}
#endif
/*
@@ -247,52 +278,48 @@ int debug = 0;
#endif
trputc(c) {
#if DEBUG
static void
trputc(int c)
{
if (tracefile == NULL)
return;
putc(c, tracefile);
if (c == '\n')
fflush(tracefile);
#endif
}
trace(fmt, a1, a2, a3, a4, a5, a6, a7, a8)
char *fmt;
{
#if DEBUG
int e = errno;
if (tracefile == NULL)
return;
fprintf(tracefile, fmt, a1, a2, a3, a4, a5, a6, a7, a8);
if (strchr(fmt, '\n'))
fflush(tracefile);
errno = e;
#endif
void
sh_trace(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
if (tracefile != NULL) {
(void) vfprintf(tracefile, fmt, va);
if (strchr(fmt, '\n'))
(void) fflush(tracefile);
}
va_end(va);
}
trputs(s)
char *s;
{
#if DEBUG
void
trputs(char *s)
{
if (tracefile == NULL)
return;
fputs(s, tracefile);
if (strchr(s, '\n'))
fflush(tracefile);
#endif
}
trstring(s)
char *s;
{
register char *p;
static void
trstring(char *s)
{
char *p;
char c;
#if DEBUG
if (tracefile == NULL)
return;
putc('"', tracefile);
@@ -324,14 +351,12 @@ backslash: putc('\\', tracefile);
}
}
putc('"', tracefile);
#endif
}
trargs(ap)
char **ap;
{
#if DEBUG
void
trargs(char **ap)
{
if (tracefile == NULL)
return;
while (*ap) {
@@ -342,36 +367,43 @@ trargs(ap)
putc('\n', tracefile);
}
fflush(tracefile);
#endif
}
opentrace() {
void
opentrace(void)
{
char s[100];
char *p;
char *getenv();
int flags;
#if DEBUG
if (!debug)
return;
if ((p = getenv("HOME")) == NULL) {
if (getuid() == 0)
p = "/";
else
p = "/tmp";
#ifdef not_this_way
{
char *p;
if ((p = getenv("HOME")) == NULL) {
if (geteuid() == 0)
p = "/";
else
p = "/tmp";
}
scopy(p, s);
strcat(s, "/trace");
}
scopy(p, s);
strcat(s, "/trace");
#else
scopy("./trace", s);
#endif /* not_this_way */
if ((tracefile = fopen(s, "a")) == NULL) {
fprintf(stderr, "Can't open %s\n", s);
fprintf(stderr, "Can't open %s: %s\n", s, strerror(errno));
return;
}
#ifdef O_APPEND
if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
#endif
fputs("\nTracing started.\n", tracefile);
fflush(tracefile);
#endif
}
#endif /* DEBUG */
/*
* $PchId: show.c,v 1.6 2006/05/22 12:27:51 philip Exp $
*/

42
commands/ash/show.h Normal file
View File

@@ -0,0 +1,42 @@
/*-
* Copyright (c) 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)show.h 1.1 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/show.h,v 1.11 2004/04/06 20:06:51 markm Exp $
*/
#ifdef DEBUG
void sh_trace(const char *, ...);
void trargs(char **);
void trputs(char *);
void opentrace(void);
#endif
/*
* $PchId: show.h,v 1.4 2006/03/29 13:28:45 philip Exp $
*/

View File

@@ -1,15 +0,0 @@
/* Replacement for something BSD has in sys/cdefs.h. */
#ifndef _ASH_SYS_CDEFS
#define _ASH_SYS_CDEFS
#if __STDC__
#define __P(params) params
#else
#define __P(params) ()
#endif
/* Probably in sys/types.h. */
typedef void (*sig_t) __P(( int ));
#endif /* _ASH_SYS_CDEFS */

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,25 +31,45 @@
*/
#ifndef lint
static char sccsid[] = "@(#)trap.c 5.2 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/trap.c,v 1.29 2004/04/06 20:06:51 markm Exp $");
*/
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include "shell.h"
#include "main.h"
#include "nodes.h" /* for other headers */
#include "eval.h"
#include "jobs.h"
#include "show.h"
#include "options.h"
#include "syntax.h"
#include "signames.h"
#include "output.h"
#include "memalloc.h"
#include "error.h"
#include "trap.h"
#include "mystring.h"
#include <sys/types.h>
#include <signal.h>
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#include "builtins.h"
#ifdef __minix
#define NO_SIGINTERRUPT
#define NO_SYS_SIGNAME
#define NO_SYS_SIGLIST
#endif
typedef void (*sig_T)(int);
/*
* Sigmode records the current value of the signal handlers for the various
@@ -64,40 +80,130 @@ static char sccsid[] = "@(#)trap.c 5.2 (Berkeley) 4/12/91";
#define S_DFL 1 /* default signal handling (SIG_DFL) */
#define S_CATCH 2 /* signal is caught */
#define S_IGN 3 /* signal is ignored (SIG_IGN) */
#define S_HARD_IGN 4 /* signal is ignored permenantly */
#define S_HARD_IGN 4 /* signal is ignored permanently */
#define S_RESET 5 /* temporary - to reset a hard ignored sig */
extern char nullstr[1]; /* null string */
MKINIT char sigmode[_NSIG]; /* current value of signal */
int pendingsigs; /* indicates some signal received */
int is_interactive= -1; /* Shell is interactive */
int in_dotrap; /* do we execute in a trap handler? */
static char *volatile trap[_NSIG]; /* trap handler commands */
static volatile sig_atomic_t gotsig[_NSIG];
/* indicates specified signal received */
static int ignore_sigchld; /* Used while handling SIGCHLD traps. */
volatile sig_atomic_t gotwinch;
static int sigstring_to_signum (char *);
static void printsignals (void);
static int getsigaction(int, sig_T *);
static void onsig (int);
#ifdef NO_SIGINTERRUPT
static int siginterrupt (int,int);
#endif
static char *strsigname (int);
/*
* Map a string to a signal number.
*/
static int
sigstring_to_signum(char *sig)
{
if (is_number(sig)) {
int signo;
signo = atoi(sig);
return ((signo >= 0 && signo < _NSIG) ? signo : (-1));
} else if (strcasecmp(sig, "exit") == 0) {
return (0);
} else {
int n;
if (strncasecmp(sig, "sig", 3) == 0)
sig += 3;
for (n = 1; n < _NSIG; n++)
if (strcasecmp(strsigname(n), sig) == 0)
return (n);
}
return (-1);
}
/*
* Print a list of valid signal names.
*/
static void
printsignals(void)
{
int n, outlen;
outlen = 0;
for (n = 1; n < _NSIG; n++) {
if (strsigname(n)) {
out1fmt("%s", strsigname(n));
outlen += strlen(strsigname(n));
} else {
out1fmt("%d", n);
outlen += 3; /* good enough */
}
++outlen;
if (outlen > 70 || n == _NSIG - 1) {
out1str("\n");
outlen = 0;
} else {
out1c(' ');
}
}
}
char *trap[MAXSIG+1]; /* trap handler commands */
MKINIT char sigmode[MAXSIG]; /* current value of signal */
char gotsig[MAXSIG]; /* indicates specified signal received */
int pendingsigs; /* indicates some signal received */
/*
* The trap builtin.
*/
trapcmd(argc, argv) char **argv; {
int
trapcmd(int argc, char **argv)
{
char *action;
char **ap;
int signo;
if (argc <= 1) {
for (signo = 0 ; signo <= MAXSIG ; signo++) {
if (trap[signo] != NULL)
out1fmt("%d: %s\n", signo, trap[signo]);
for (signo = 0 ; signo < _NSIG ; signo++) {
if (trap[signo] != NULL) {
if (signo == 0) {
out1fmt("trap -- '%s' %s\n",
trap[signo], "exit");
} else if (strsigname(signo)) {
out1fmt("trap -- '%s' %s\n",
trap[signo], strsigname(signo));
} else {
out1fmt("trap -- '%s' %d\n",
trap[signo], signo);
}
}
}
return 0;
}
ap = argv + 1;
if (is_number(*ap))
action = NULL;
else
action = *ap++;
while (*ap) {
if ((signo = number(*ap)) < 0 || signo > MAXSIG)
error("%s: bad trap", *ap);
action = NULL;
if (*++argv && strcmp(*argv, "--") == 0)
argv++;
if (*argv && sigstring_to_signum(*argv) == -1) {
if ((*argv)[0] != '-') {
action = *argv;
argv++;
} else if ((*argv)[1] == '\0') {
argv++;
} else if ((*argv)[1] == 'l' && (*argv)[2] == '\0') {
printsignals();
return 0;
} else {
error("bad option %s", *argv);
}
}
while (*argv) {
if ((signo = sigstring_to_signum(*argv)) == -1)
error("bad signal %s", *argv);
INTOFF;
if (action)
action = savestr(action);
@@ -107,22 +213,21 @@ trapcmd(argc, argv) char **argv; {
if (signo != 0)
setsignal(signo);
INTON;
ap++;
argv++;
}
return 0;
}
/*
* Clear traps on a fork.
*/
void
clear_traps() {
char **tp;
clear_traps(void)
{
char *volatile *tp;
for (tp = trap ; tp <= &trap[MAXSIG] ; tp++) {
for (tp = trap ; tp <= &trap[_NSIG - 1] ; tp++) {
if (*tp && **tp) { /* trap not NULL or SIG_IGN */
INTOFF;
ckfree(*tp);
@@ -135,18 +240,16 @@ clear_traps() {
}
/*
* Set the signal handler for the specified signal. The routine figures
* out what it should be set to.
*/
int
setsignal(signo) {
void
setsignal(int signo)
{
int action;
sig_t sigact;
sig_T sig, sigact = SIG_DFL;
char *t;
extern void onsig();
if ((t = trap[signo]) == NULL)
action = S_DFL;
@@ -154,11 +257,10 @@ setsignal(signo) {
action = S_CATCH;
else
action = S_IGN;
if (rootshell && action == S_DFL) {
if (action == S_DFL) {
switch (signo) {
case SIGINT:
if (iflag)
action = S_CATCH;
action = S_CATCH;
break;
case SIGQUIT:
#if DEBUG
@@ -169,68 +271,103 @@ setsignal(signo) {
break;
}
#endif
/* FALLTHROUGH */
action = S_CATCH;
break;
case SIGTERM:
if (iflag)
if (rootshell && iflag)
action = S_IGN;
break;
#if JOBS
case SIGTSTP:
case SIGTTOU:
if (jflag)
if (rootshell && mflag)
action = S_IGN;
break;
#endif
#ifndef NO_HISTORY
case SIGWINCH:
if (rootshell && iflag)
action = S_CATCH;
break;
#endif
}
}
t = &sigmode[signo - 1];
if (*t == 0) { /* current setting unknown */
t = &sigmode[signo];
if (*t == 0) {
/*
* There is a race condition here if action is not S_IGN.
* A signal can be ignored that shouldn't be.
* current setting unknown
*/
if ((int)(sigact = signal(signo, SIG_IGN)) == -1)
error("Signal system call failed");
if (!getsigaction(signo, &sigact)) {
/*
* Pretend it worked; maybe we should give a warning
* here, but other shells don't. We don't alter
* sigmode, so that we retry every time.
*/
return;
}
if (sigact == SIG_IGN) {
*t = S_HARD_IGN;
if (mflag && (signo == SIGTSTP ||
signo == SIGTTIN || signo == SIGTTOU)) {
*t = S_IGN; /* don't hard ignore these */
} else
*t = S_HARD_IGN;
} else {
*t = S_IGN;
*t = S_RESET; /* force to be set */
}
}
if (*t == S_HARD_IGN || *t == action)
return 0;
return;
switch (action) {
case S_DFL: sigact = SIG_DFL; break;
case S_CATCH: sigact = onsig; break;
case S_IGN: sigact = SIG_IGN; break;
}
*t = action;
return (int)signal(signo, sigact);
sig = signal(signo, sigact);
if (sig != SIG_ERR && action == S_CATCH)
siginterrupt(signo, 1);
}
/*
* Return the current setting for sig w/o changing it.
*/
static int
getsigaction(int signo, sig_T *sigact)
{
struct sigaction sa;
if (sigaction(signo, (struct sigaction *)0, &sa) == -1)
return 0;
*sigact = (sig_T) sa.sa_handler;
return 1;
}
/*
* Ignore a signal.
*/
void
ignoresig(signo) {
if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) {
ignoresig(int signo)
{
if (sigmode[signo] != S_IGN && sigmode[signo] != S_HARD_IGN) {
signal(signo, SIG_IGN);
}
sigmode[signo - 1] = S_HARD_IGN;
sigmode[signo] = S_HARD_IGN;
}
#ifdef mkinit
INCLUDE "signames.h"
INCLUDE <signal.h>
INCLUDE "trap.h"
SHELLPROC {
char *sm;
clear_traps();
for (sm = sigmode ; sm < sigmode + MAXSIG ; sm++) {
for (sm = sigmode ; sm < sigmode + _NSIG ; sm++) {
if (*sm == S_IGN)
*sm = S_HARD_IGN;
}
@@ -238,82 +375,119 @@ SHELLPROC {
#endif
/*
* Signal handler.
*/
static void
onsig(int signo)
{
void
onsig(signo) {
#ifndef BSD
signal(signo, onsig);
#endif
if (signo == SIGINT && trap[SIGINT] == NULL) {
onint();
return;
}
gotsig[signo - 1] = 1;
pendingsigs++;
}
if (signo != SIGCHLD || !ignore_sigchld)
gotsig[signo] = 1;
pendingsigs++;
/* If we are currently in a wait builtin, prepare to break it */
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
breakwaitcmd = 1;
/*
* If a trap is set, not ignored and not the null command, we need
* to make sure traps are executed even when a child blocks signals.
*/
if (Tflag &&
trap[signo] != NULL &&
! trap[signo][0] == '\0' &&
! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
breakwaitcmd = 1;
#ifndef NO_HISTORY
if (signo == SIGWINCH)
gotwinch = 1;
#endif
}
/*
* Called to execute a trap. Perhaps we should avoid entering new trap
* handlers while we are executing a trap handler.
*/
void
dotrap() {
dotrap(void)
{
int i;
int savestatus;
in_dotrap++;
for (;;) {
for (i = 1 ; ; i++) {
if (gotsig[i - 1])
for (i = 1; i < _NSIG; i++) {
if (gotsig[i]) {
gotsig[i] = 0;
if (trap[i]) {
/*
* Ignore SIGCHLD to avoid infinite
* recursion if the trap action does
* a fork.
*/
if (i == SIGCHLD)
ignore_sigchld++;
savestatus = exitstatus;
evalstring(trap[i]);
exitstatus = savestatus;
if (i == SIGCHLD)
ignore_sigchld--;
}
break;
if (i >= MAXSIG)
goto done;
}
}
gotsig[i - 1] = 0;
savestatus=exitstatus;
evalstring(trap[i]);
exitstatus=savestatus;
if (i >= _NSIG)
break;
}
done:
in_dotrap--;
pendingsigs = 0;
}
/*
* Controls whether the shell is interactive or not.
*/
int is_interactive;
void
setinteractive(on) {
setinteractive(int on)
{
if (on == is_interactive)
return;
setsignal(SIGINT);
setsignal(SIGQUIT);
setsignal(SIGTERM);
#ifndef NO_HISTORY
setsignal(SIGWINCH);
#endif
is_interactive = on;
}
/*
* Called to exit the shell.
*/
void
exitshell(status) {
exitshell(int status)
{
struct jmploc loc1, loc2;
char *p;
TRACE(("exitshell(%d) pid=%d\n", status, getpid()));
if (setjmp(loc1.loc)) goto l1;
if (setjmp(loc2.loc)) goto l2;
if (setjmp(loc1.loc)) {
goto l1;
}
if (setjmp(loc2.loc)) {
goto l2;
}
handler = &loc1;
if ((p = trap[0]) != NULL && *p != '\0') {
trap[0] = NULL;
@@ -326,3 +500,85 @@ l1: handler = &loc2; /* probably unnecessary */
#endif
l2: _exit(status);
}
#ifdef NO_SIGINTERRUPT
static int siginterrupt(sig, flag)
int sig;
int flag;
{
return 0;
}
#endif
#ifdef NO_SYS_SIGNAME
static char *strsigname(sig)
int sig;
{
switch(sig)
{
case 0: return "Signal 0"; /* 0 */
case SIGHUP: return "hup"; /* 1 */
case SIGINT: return "int"; /* 2 */
case SIGQUIT: return "quit"; /* 3 */
case SIGILL: return "ill"; /* 4 */
case SIGTRAP: return "trap"; /* 5 */
case SIGABRT: return "abrt"; /* 6 */
#ifdef __minix_vmd
case SIGEMT: return "emt"; /* 7 */
#else
case SIGBUS: return "bus"; /* 7 */
#endif
case SIGFPE: return "fpe"; /* 8 */
case SIGKILL: return "kill"; /* 9 */
case SIGUSR1: return "usr1"; /* 10 */
case SIGSEGV: return "segv"; /* 11 */
case SIGUSR2: return "usr2"; /* 12 */
case SIGPIPE: return "pipe"; /* 13 */
case SIGALRM: return "alrm"; /* 14 */
case SIGTERM: return "term"; /* 15 */
#ifdef __minix_vmd
case 16: return "Signal 16"; /* 16 */
#else
case SIGEMT: return "emt"; /* 16 */
#endif
case SIGCHLD: return "chld"; /* 17 */
case SIGCONT: return "cont"; /* 18 */
case SIGSTOP: return "stop"; /* 19 */
case SIGTSTP: return "tstp"; /* 20 */
case SIGTTIN: return "ttin"; /* 21 */
case SIGTTOU: return "ttou"; /* 22 */
case SIGWINCH: return "winch"; /* 23 */
#ifdef __minix_vmd
case SIGFPEMU: return "fpemu"; /* 30 */
#endif
default: return "Signal n";
}
}
#else
static char *strsigname(sig)
int sig;
{
return sys_signame[sig];
}
#endif
#ifdef NO_SYS_SIGLIST
#include "signames.h"
char *strsiglist(sig)
int sig;
{
if (sig > MAXSIG)
return NULL;
return sigmesg[sig];
}
#else
char *strsiglist(sig)
int sig;
{
return sys_siglist[sig];
}
#endif
/*
* $PchId: trap.c,v 1.7 2006/05/23 11:56:21 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,23 +29,24 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)trap.h 5.1 (Berkeley) 3/7/91
* @(#)trap.h 8.3 (Berkeley) 6/5/95
* $FreeBSD: src/bin/sh/trap.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
extern int pendingsigs;
extern int in_dotrap;
extern int is_interactive;
extern volatile sig_atomic_t gotwinch;
#ifdef __STDC__
int trapcmd(int, char **);
void clear_traps(void);
int setsignal(int);
void setsignal(int);
void ignoresig(int);
void dotrap(void);
void setinteractive(int);
void exitshell(int);
#else
void clear_traps();
int setsignal();
void ignoresig();
void dotrap();
void setinteractive();
void exitshell();
#endif
char *strsiglist(int);
/*
* $PchId: trap.h,v 1.6 2006/05/22 12:48:30 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -35,13 +31,27 @@
*/
#ifndef lint
static char sccsid[] = "@(#)var.c 5.3 (Berkeley) 4/12/91";
#if 0
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95";
#endif
#endif /* not lint */
/*
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/bin/sh/var.c,v 1.26.2.1 2004/09/30 04:41:55 des Exp $");
*/
#include <unistd.h>
#include <stdlib.h>
#ifndef NO_PATHS_H
#include <paths.h>
#endif
/*
* Shell variables.
*/
#include <locale.h>
#include "shell.h"
#include "output.h"
#include "expand.h"
@@ -55,7 +65,16 @@ static char sccsid[] = "@(#)var.c 5.3 (Berkeley) 4/12/91";
#include "memalloc.h"
#include "error.h"
#include "mystring.h"
#include "parser.h"
#if !defined(NO_HISTORY) && !defined(EDITLINE)
#include "myhistedit.h"
#endif
#include "builtins.h"
#ifndef _PATH_DEFPATH
#define _PATH_DEFPATH "/usr/bin:/bin"
#endif
#define VTABSIZE 39
@@ -64,48 +83,57 @@ struct varinit {
struct var *var;
int flags;
char *text;
void (*func)(const char *);
};
#if ATTY
struct var vatty;
#ifndef NO_HISTORY
struct var vhistsize;
#endif
struct var vifs;
struct var vmail;
struct var vmpath;
struct var vpath;
struct var vppid;
struct var vps1;
struct var vps2;
struct var vpse;
struct var vvers;
#if ATTY
struct var vterm;
#endif
STATIC struct var voptind;
const struct varinit varinit[] = {
#if ATTY
{&vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY="},
STATIC const struct varinit varinit[] = {
#if !defined(NO_HISTORY) && !defined(EDITLINE)
{ &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=",
sethistsize },
#endif
{&vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n"},
{&vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL="},
{&vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH="},
{&vpath, VSTRFIXED|VTEXTFIXED, "PATH=:/bin:/usr/bin"},
/*
{ &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n",
NULL },
{ &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=",
NULL },
{ &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=",
NULL },
{ &vpath, VSTRFIXED|VTEXTFIXED, "PATH=" _PATH_DEFPATH,
changepath },
{ &vppid, VSTRFIXED|VTEXTFIXED|VUNSET, "PPID=",
NULL },
/*
* vps1 depends on uid
*/
{&vps2, VSTRFIXED|VTEXTFIXED, "PS2=> "},
{&vpse, VSTRFIXED|VTEXTFIXED, "PSE=* "},
#if ATTY
{&vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM="},
#endif
{NULL, 0, NULL}
{ &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ",
NULL },
{ &vpse, VSTRFIXED|VTEXTFIXED|VUNSET, "PSE=",
NULL },
{ &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1",
getoptsreset },
{ NULL, 0, NULL,
NULL }
};
struct var *vartab[VTABSIZE];
STATIC struct var *vartab[VTABSIZE];
STATIC void unsetvar __P((char *));
STATIC struct var **hashvar __P((char *));
STATIC int varequal __P((char *, char *));
STATIC struct var **hashvar(char *);
STATIC int varequal(char *, char *);
STATIC int localevar(char *);
/*
* Initialize the varable symbol tables and import the environment
@@ -133,7 +161,9 @@ INIT {
*/
void
initvar() {
initvar(void)
{
char ppid[20];
const struct varinit *ip;
struct var *vp;
struct var **vpp;
@@ -145,6 +175,7 @@ initvar() {
*vpp = vp;
vp->text = ip->text;
vp->flags = ip->flags;
vp->func = ip->func;
}
}
/*
@@ -154,20 +185,48 @@ initvar() {
vpp = hashvar("PS1=");
vps1.next = *vpp;
*vpp = &vps1;
vps1.text = getuid() ? "PS1=$ " : "PS1=# ";
vps1.text = geteuid() ? "PS1=$ " : "PS1=# ";
vps1.flags = VSTRFIXED|VTEXTFIXED;
}
if ((vppid.flags & VEXPORT) == 0) {
fmtstr(ppid, sizeof(ppid), "%d", (int)getppid());
setvarsafe("PPID", ppid, 0);
}
}
/*
* Set the value of a variable. The flags argument is ored with the
* Safe version of setvar, returns 1 on success 0 on failure.
*/
int
setvarsafe(char *name, char *val, int flags)
{
struct jmploc jmploc;
struct jmploc *volatile savehandler = handler;
int err = 0;
#if __GNUC__
/* Avoid longjmp clobbering */
(void) &err;
#endif
if (setjmp(jmploc.loc))
err = 1;
else {
handler = &jmploc;
setvar(name, val, flags);
}
handler = savehandler;
return err;
}
/*
* Set the value of a variable. The flags argument is tored with the
* flags of the variable. If val is NULL, the variable is unset.
*/
void
setvar(name, val, flags)
char *name, *val;
{
setvar(char *name, char *val, int flags)
{
char *p, *q;
int len;
int namelen;
@@ -176,8 +235,9 @@ setvar(name, val, flags)
isbad = 0;
p = name;
if (! is_name(*p++))
if (! is_name(*p))
isbad = 1;
p++;
for (;;) {
if (! is_in_name(*p)) {
if (*p == '\0' || *p == '=')
@@ -188,7 +248,7 @@ setvar(name, val, flags)
}
namelen = p - name;
if (isbad)
error("%.*s: is read only", namelen, name);
error("%.*s: bad variable name", namelen, name);
len = namelen + 2; /* 2 is space for '=' and '\0' */
if (val == NULL) {
flags |= VUNSET;
@@ -206,7 +266,26 @@ setvar(name, val, flags)
setvareq(nameeq, flags);
}
STATIC int
localevar(char *s)
{
static char *lnames[7] = {
"ALL", "COLLATE", "CTYPE", "MONETARY",
"NUMERIC", "TIME", NULL
};
char **ss;
if (*s != 'L')
return 0;
if (varequal(s + 1, "ANG"))
return 1;
if (strncmp(s + 1, "C_", 2) != 0)
return 0;
for (ss = lnames; *ss ; ss++)
if (varequal(s + 3, *ss))
return 1;
return 0;
}
/*
* Same as setvar except that the variable and value are passed in
@@ -216,28 +295,42 @@ setvar(name, val, flags)
*/
void
setvareq(s, flags)
char *s;
{
setvareq(char *s, int flags)
{
struct var *vp, **vpp;
int len;
if (aflag)
flags |= VEXPORT;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(s, vp->text)) {
if (vp->flags & VREADONLY) {
int len = strchr(s, '=') - s;
len = strchr(s, '=') - s;
error("%.*s: is read only", len, s);
}
INTOFF;
if (vp == &vpath)
changepath(s + 5); /* 5 = strlen("PATH=") */
if (vp->func && (flags & VNOFUNC) == 0)
(*vp->func)(strchr(s, '=') + 1);
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0)
ckfree(vp->text);
vp->flags &=~ (VTEXTFIXED|VSTACK|VUNSET);
vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET);
vp->flags |= flags;
vp->text = s;
/*
* We could roll this to a function, to handle it as
* a regular variable function callback, but why bother?
*/
if (vp == &vmpath || (vp == &vmail && ! mpathset()))
chkmail(1);
if ((vp->flags & VEXPORT) && localevar(s)) {
putenv(s);
(void) setlocale(LC_ALL, "");
}
INTON;
return;
}
@@ -247,7 +340,14 @@ setvareq(s, flags)
vp->flags = flags;
vp->text = s;
vp->next = *vpp;
vp->func = NULL;
INTOFF;
*vpp = vp;
if ((vp->flags & VEXPORT) && localevar(s)) {
putenv(s);
(void) setlocale(LC_ALL, "");
}
INTON;
}
@@ -257,9 +357,8 @@ setvareq(s, flags)
*/
void
listsetvar(list)
struct strlist *list;
{
listsetvar(struct strlist *list)
{
struct strlist *lp;
INTOFF;
@@ -276,9 +375,8 @@ listsetvar(list)
*/
char *
lookupvar(name)
char *name;
{
lookupvar(char *name)
{
struct var *v;
for (v = *hashvar(name) ; v ; v = v->next) {
@@ -300,9 +398,8 @@ lookupvar(name)
*/
char *
bltinlookup(name, doall)
char *name;
{
bltinlookup(char *name, int doall)
{
struct strlist *sp;
struct var *v;
@@ -312,8 +409,8 @@ bltinlookup(name, doall)
}
for (v = *hashvar(name) ; v ; v = v->next) {
if (varequal(v->text, name)) {
if (v->flags & VUNSET
|| ! doall && (v->flags & VEXPORT) == 0)
if ((v->flags & VUNSET)
|| (!doall && (v->flags & VEXPORT) == 0))
return NULL;
return strchr(v->text, '=') + 1;
}
@@ -329,7 +426,8 @@ bltinlookup(name, doall)
*/
char **
environment() {
environment(void)
{
int nenv;
struct var **vpp;
struct var *vp;
@@ -359,15 +457,14 @@ environment() {
*/
#ifdef mkinit
MKINIT void shprocvar();
SHELLPROC {
shprocvar();
}
#endif
void
shprocvar() {
shprocvar(void)
{
struct var **vpp;
struct var *vp, **prev;
@@ -400,14 +497,21 @@ shprocvar() {
*/
int
showvarscmd(argc, argv) char **argv; {
showvarscmd(int argc __unused, char **argv __unused)
{
struct var **vpp;
struct var *vp;
const char *s;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if ((vp->flags & VUNSET) == 0)
out1fmt("%s\n", vp->text);
if (vp->flags & VUNSET)
continue;
for (s = vp->text; *s != '='; s++)
out1c(*s);
out1c('=');
out1qstr(s + 1);
out1c('\n');
}
}
return 0;
@@ -420,15 +524,35 @@ showvarscmd(argc, argv) char **argv; {
*/
int
exportcmd(argc, argv) char **argv; {
exportcmd(int argc, char **argv)
{
struct var **vpp;
struct var *vp;
char *name;
char *p;
char *cmdname;
int ch, values;
int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT;
cmdname = argv[0];
optreset = optind = 1;
opterr = 0;
values = 0;
while ((ch = getopt(argc, argv, "p")) != -1) {
switch (ch) {
case 'p':
values = 1;
break;
case '?':
default:
error("unknown option: -%c", optopt);
}
}
argc -= optind;
argv += optind;
listsetvar(cmdenviron);
if (argc > 1) {
if (argc != 0) {
while ((name = *argptr++) != NULL) {
if ((p = strchr(name, '=')) != NULL) {
p++;
@@ -436,7 +560,12 @@ exportcmd(argc, argv) char **argv; {
vpp = hashvar(name);
for (vp = *vpp ; vp ; vp = vp->next) {
if (varequal(vp->text, name)) {
vp->flags |= flag;
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
putenv(vp->text);
(void) setlocale(LC_ALL, "");
}
goto found;
}
}
@@ -448,8 +577,16 @@ found:;
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) {
for (vp = *vpp ; vp ; vp = vp->next) {
if (vp->flags & flag) {
if (values) {
out1str(cmdname);
out1c(' ');
}
for (p = vp->text ; *p != '=' ; p++)
out1c(*p);
if (values && !(vp->flags & VUNSET)) {
out1c('=');
out1qstr(p + 1);
}
out1c('\n');
}
}
@@ -463,7 +600,9 @@ found:;
* The "local" command.
*/
localcmd(argc, argv) char **argv; {
int
localcmd(int argc __unused, char **argv __unused)
{
char *name;
if (! in_function())
@@ -483,9 +622,8 @@ localcmd(argc, argv) char **argv; {
*/
void
mklocal(name)
char *name;
{
mklocal(char *name)
{
struct localvar *lvp;
struct var **vpp;
struct var *vp;
@@ -493,8 +631,8 @@ mklocal(name)
INTOFF;
lvp = ckmalloc(sizeof (struct localvar));
if (name[0] == '-' && name[1] == '\0') {
lvp->text = ckmalloc(sizeof optval);
bcopy(optval, lvp->text, sizeof optval);
lvp->text = ckmalloc(sizeof optlist);
memcpy(lvp->text, optlist, sizeof optlist);
vp = NULL;
} else {
vpp = hashvar(name);
@@ -527,7 +665,8 @@ mklocal(name)
*/
void
poplocalvars() {
poplocalvars(void)
{
struct localvar *lvp;
struct var *vp;
@@ -535,10 +674,10 @@ poplocalvars() {
localvars = lvp->next;
vp = lvp->vp;
if (vp == NULL) { /* $- saved */
bcopy(lvp->text, optval, sizeof optval);
memcpy(optlist, lvp->text, sizeof optlist);
ckfree(lvp->text);
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) {
unsetvar(vp->text);
(void)unsetvar(vp->text);
} else {
if ((vp->flags & VTEXTFIXED) == 0)
ckfree(vp->text);
@@ -550,7 +689,9 @@ poplocalvars() {
}
setvarcmd(argc, argv) char **argv; {
int
setvarcmd(int argc, char **argv)
{
if (argc <= 2)
return unsetcmd(argc, argv);
else if (argc == 3)
@@ -567,14 +708,31 @@ setvarcmd(argc, argv) char **argv; {
* with the same name.
*/
unsetcmd(argc, argv) char **argv; {
int
unsetcmd(int argc __unused, char **argv __unused)
{
char **ap;
int i;
int flg_func = 0;
int flg_var = 0;
int ret = 0;
for (ap = argv + 1 ; *ap ; ap++) {
unsetfunc(*ap);
unsetvar(*ap);
while ((i = nextopt("vf")) != '\0') {
if (i == 'f')
flg_func = 1;
else
flg_var = 1;
}
return 0;
if (flg_func == 0 && flg_var == 0)
flg_var = 1;
for (ap = argptr; *ap ; ap++) {
if (flg_func)
ret |= unsetfunc(*ap);
if (flg_var)
ret |= unsetvar(*ap);
}
return ret;
}
@@ -582,22 +740,25 @@ unsetcmd(argc, argv) char **argv; {
* Unset the specified variable.
*/
STATIC void
unsetvar(s)
char *s;
{
int
unsetvar(char *s)
{
struct var **vpp;
struct var *vp;
vpp = hashvar(s);
for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) {
if (varequal(vp->text, s)) {
if (vp->flags & VREADONLY)
return (1);
INTOFF;
if (*(strchr(vp->text, '=') + 1) != '\0'
|| vp->flags & VREADONLY) {
if (*(strchr(vp->text, '=') + 1) != '\0')
setvar(s, nullstr, 0);
if ((vp->flags & VEXPORT) && localevar(vp->text)) {
unsetenv(s);
setlocale(LC_ALL, "");
}
vp->flags &=~ VEXPORT;
vp->flags &= ~VEXPORT;
vp->flags |= VUNSET;
if ((vp->flags & VSTRFIXED) == 0) {
if ((vp->flags & VTEXTFIXED) == 0)
@@ -606,9 +767,11 @@ unsetvar(s)
ckfree(vp);
}
INTON;
return;
return (0);
}
}
return (0);
}
@@ -618,14 +781,13 @@ unsetvar(s)
*/
STATIC struct var **
hashvar(p)
register char *p;
{
hashvar(char *p)
{
unsigned int hashval;
hashval = *p << 4;
hashval = ((unsigned char) *p) << 4;
while (*p && *p != '=')
hashval += *p++;
hashval += (unsigned char) *p++;
return &vartab[hashval % VTABSIZE];
}
@@ -638,9 +800,8 @@ hashvar(p)
*/
STATIC int
varequal(p, q)
register char *p, *q;
{
varequal(char *p, char *q)
{
while (*p == *q++) {
if (*p++ == '=')
return 1;
@@ -649,3 +810,7 @@ varequal(p, q)
return 1;
return 0;
}
/*
* $PchId: var.c,v 1.5 2006/05/22 12:28:49 philip Exp $
*/

View File

@@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Kenneth Almquist.
@@ -13,10 +13,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
@@ -33,7 +29,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)var.h 5.1 (Berkeley) 3/7/91
* @(#)var.h 8.2 (Berkeley) 5/4/95
* $FreeBSD: src/bin/sh/var.h,v 1.12 2004/04/06 20:06:51 markm Exp $
*/
/*
@@ -41,43 +38,45 @@
*/
/* flags */
#define VEXPORT 01 /* variable is exported */
#define VREADONLY 02 /* variable cannot be modified */
#define VSTRFIXED 04 /* variable struct is staticly allocated */
#define VTEXTFIXED 010 /* text is staticly allocated */
#define VSTACK 020 /* text is allocated on the stack */
#define VUNSET 040 /* the variable is not set */
#define VEXPORT 0x01 /* variable is exported */
#define VREADONLY 0x02 /* variable cannot be modified */
#define VSTRFIXED 0x04 /* variable struct is staticly allocated */
#define VTEXTFIXED 0x08 /* text is staticly allocated */
#define VSTACK 0x10 /* text is allocated on the stack */
#define VUNSET 0x20 /* the variable is not set */
#define VNOFUNC 0x40 /* don't call the callback function */
struct var {
struct var *next; /* next entry in hash list */
int flags; /* flags are defined above */
char *text; /* name=value */
int flags; /* flags are defined above */
char *text; /* name=value */
void (*func)(const char *);
/* function to be called when */
/* the variable gets set/unset */
};
struct localvar {
struct localvar *next; /* next local variable in list */
struct var *vp; /* the variable that was made local */
int flags; /* saved flags */
char *text; /* saved text */
struct localvar *next; /* next local variable in list */
struct var *vp; /* the variable that was made local */
int flags; /* saved flags */
char *text; /* saved text */
};
struct localvar *localvars;
#if ATTY
extern struct var vatty;
#endif
extern struct var vifs;
extern struct var vmail;
extern struct var vmpath;
extern struct var vpath;
extern struct var vppid;
extern struct var vps1;
extern struct var vps2;
extern struct var vpse;
#if ATTY
extern struct var vterm;
#ifndef NO_HISTORY
extern struct var vhistsize;
#endif
/*
@@ -87,43 +86,39 @@ extern struct var vterm;
*/
#define ifsval() (vifs.text + 4)
#define ifsset() ((vifs.flags & VUNSET) == 0)
#define mailval() (vmail.text + 5)
#define mpathval() (vmpath.text + 9)
#define pathval() (vpath.text + 5)
#define ps1val() (vps1.text + 4)
#define ps2val() (vps2.text + 4)
#define pseval() (vpse.text + 4)
#if ATTY
#define termval() (vterm.text + 5)
#define optindval() (voptind.text + 7)
#ifndef NO_HISTORY
#define histsizeval() (vhistsize.text + 9)
#endif
#if ATTY
#define attyset() ((vatty.flags & VUNSET) == 0)
#endif
#define mpathset() ((vmpath.flags & VUNSET) == 0)
#ifdef __STDC__
void initvar();
void initvar(void);
void setvar(char *, char *, int);
void setvareq(char *, int);
struct strlist;
void listsetvar(struct strlist *);
char *lookupvar(char *);
char *bltinlookup(char *, int);
char **environment();
char **environment(void);
void shprocvar(void);
int showvarscmd(int, char **);
int exportcmd(int, char **);
int localcmd(int, char **);
void mklocal(char *);
void poplocalvars(void);
#else
void initvar();
void setvar();
void setvareq();
void listsetvar();
char *lookupvar();
char *bltinlookup();
char **environment();
int showvarscmd();
void mklocal();
void poplocalvars();
#endif
int setvarcmd(int, char **);
int unsetcmd(int, char **);
int unsetvar(char *);
int setvarsafe(char *, char *, int);
/*
* $PchId: var.h,v 1.4 2006/03/29 12:04:45 philip Exp $
*/

View File

@@ -1,38 +0,0 @@
a small AWK clone
このプログラムは、Minix 1.2 用に書いたものです。浮動小数点演算を使い
ますから、Minix 1.5 以前の ACK-C ではコンパイルできません。そのため makefile
では、Peter S. Houselさんの浮動小数点パッケージを使うようになっています。
CFLAGS の -f が、その指示です。この浮動小数点パッケージは、非常によくできて
いますが、atan(x, y) の引き数の順序が逆になっていますので、修正しておいてく
ださい。他にも何かあったような記憶がありますが、忘れてしまいました。もし、何
か問題があるようでしたら、ご連絡いただければ、私が自分で使っているものを公表
するようにします。
このプログラムは、Shift-JIS の漢字コードを扱うようになっています。
EUC に対応させる場合は、正規表現の扱い等、漢字コードに関係する部分の書換が必
要ですが、大した手間ではありません。どなたか変更された場合は、パッチを用意し
ていただけると嬉しいです。
当初は、昔の awk の仕様になっていましたが、「AWK Programming Language」
が出版され、POSIX 1003.2 の draft でも nawk 仕様が採用されたのを機会に、nawk
の仕様に書き換えました。オリジナルの awk と違って、parser も lexical analizer
も hand maid ですから、64K+64K のメモリに収まっています。
本来は、Minix らしい、教材的なプログラムにすべきですし、そうしたかっ
たのですが、もともと、自分たちが使うために、メモもとらずにスクリーンを見なが
ら書いてしまったため、きれいなコーディングになっていません。しかし、64K+64K
のメモリで使える awk が他にありませんので、とりあえず現行の状態で公開しておく
ことにしました。
プログラムそのものは、正規表現の評価順序に依存するものを除いて、「AWK
Programming Language」に掲載されているテストプログラムに通ることを確認してあ
ります。
32-bit Minix の場合は、AT&T オジナルの awk とか gawk, mawk といった
プログラムが使えますが、浮動小数点をサポートした、c386 でこのプログラムをコ
ンパイルすることもできます。
平林 浩一 (kh@hiraide.mogami-wire.co.jp) 1995-01-29

View File

@@ -1,341 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@@ -1,89 +0,0 @@
# Makefile for bc
# A makefile for bc. This is part of the bc/sbc distribution.
#
#
# Make sure these have the correct directories for your machine.
#
# LIBDIR and BINDIR are where bc and libmath.b will be put.
#
PREFIX = /usr
LIBDIR = $(PREFIX)/lib
BINDIR = $(PREFIX)/bin
#
# Programs definitions for use by make.
#
SHELL = /bin/sh
YACC = yacc
#YACC = bison -y
LEX = flex -I8
#LEX = lex
CC = exec cc
CFLAGS = -D_POSIX_SOURCE
LDFLAGS = -i
#
#
OFILES = scan.o util.o main.o number.o storage.o load.o execute.o
#
SUBDIRS = Examples Test
#
all: bc
bc: $& config.h bc.o $(OFILES) global.o
$(CC) -o bc $(LDFLAGS) bc.o $(OFILES) global.o
sbc: sbc.o $(OFILES) global.o
$(CC) -o sbc $(LDFLAGS) sbc.o $(OFILES) global.o
math.h: libmath.b
$(MAKE) -$(MAKEFLAGS) fbc
./fbc -c libmath.b </dev/null >math.h
/bin/sh ./fix_math.h
rm -f ./fbc
fbc: $(OFILES) bc.o
echo \"\" > math.h
$(CC) -c $(CFLAGS) global.c
$(CC) -o fbc $(LDFLAGS) bc.o $(OFILES) global.o
install: $(BINDIR)/bc $(LIBDIR)/libmath.b
$(BINDIR)/bc: bc
install -cs -o bin $? $@
$(LIBDIR)/libmath.b: libmath.b
install -c -o bin $? $@
clean:
rm -f *.o *.bak core math.h bc sbc
scan.c: scan.l
$(LEX) scan.l
mv lex.yy.c scan.c
scan.o: scan.c
$(CC) -c $(CFLAGS) -wa scan.c
y.tab.h bc.c: bc.y
@echo "expect 1 shift/reduce conflict"
$(YACC) -d bc.y
mv y.tab.c bc.c
sbc.c: sbc.y
$(YACC) -d sbc.y
mv y.tab.c sbc.c
global.o: bcdefs.h global.h math.h
bc.o: bcdefs.h global.h
execute.o: bcdefs.h global.h
load.o: bcdefs.h global.h
main.o: bcdefs.h global.h version.h
number.o: bcdefs.h
sbc.o: bcdefs.h global.h
scan.o: y.tab.h bcdefs.h global.h
storage.o: bcdefs.h global.h
util.o: bcdefs.h global.h version.h
bcdefs.h: number.h const.h config.h
touch bcdefs.h

File diff suppressed because it is too large Load Diff

View File

@@ -1,612 +0,0 @@
%{
/* bc.y: The grammar for a POSIX compatable bc processor with some
extensions to the language. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include "bcdefs.h"
#include "global.h"
#include "proto.h"
%}
%start program
%union {
char *s_value;
char c_value;
int i_value;
arg_list *a_value;
}
/* Extensions over POSIX bc.
a) NAME was LETTER. This grammer allows longer names.
Single letter names will still work.
b) Relational_expression allowed only one comparison.
This grammar has added boolean expressions with
&& (and) || (or) and ! (not) and allowed all of them in
full expressions.
c) Added an else to the if.
d) Call by variable array parameters
e) read() procedure that reads a number under program control from stdin.
f) halt statement that halts the the program under program control. It
is an executed statement.
g) continue statement for for loops.
h) optional expressions in the for loop.
i) print statement to print multiple numbers per line.
j) warranty statement to print an extended warranty notice.
j) limits statement to print the processor's limits.
*/
%token <i_value> NEWLINE AND OR NOT
%token <s_value> STRING NAME NUMBER
/* '-', '+' are tokens themselves */
%token <c_value> MUL_OP
/* '*', '/', '%' */
%token <c_value> ASSIGN_OP
/* '=', '+=', '-=', '*=', '/=', '%=', '^=' */
%token <s_value> REL_OP
/* '==', '<=', '>=', '!=', '<', '>' */
%token <c_value> INCR_DECR
/* '++', '--' */
%token <i_value> Define Break Quit Length
/* 'define', 'break', 'quit', 'length' */
%token <i_value> Return For If While Sqrt Else
/* 'return', 'for', 'if', 'while', 'sqrt', 'else' */
%token <i_value> Scale Ibase Obase Auto Read
/* 'scale', 'ibase', 'obase', 'auto', 'read' */
%token <i_value> Warranty, Halt, Last, Continue, Print, Limits
/* 'warranty', 'halt', 'last', 'continue', 'print', 'limits' */
/* Types of all other things. */
%type <i_value> expression return_expression named_expression opt_expression
%type <c_value> '+' '-'
%type <a_value> opt_parameter_list opt_auto_define_list define_list
%type <a_value> opt_argument_list argument_list
%type <i_value> program input_item semicolon_list statement_list
%type <i_value> statement function statement_or_error
/* precedence */
%left OR
%left AND
%nonassoc NOT
%left REL_OP
%right ASSIGN_OP
%left '+' '-'
%left MUL_OP
%right '^'
%nonassoc UNARY_MINUS
%nonassoc INCR_DECR
%%
program : /* empty */
{
$$ = 0;
if (interactive)
{
printf ("%s\n", BC_VERSION);
welcome ();
}
}
| program input_item
;
input_item : semicolon_list NEWLINE
{ run_code (); }
| function
{ run_code (); }
| error NEWLINE
{
yyerrok;
init_gen ();
}
;
semicolon_list : /* empty */
{ $$ = 0; }
| statement_or_error
| semicolon_list ';' statement_or_error
| semicolon_list ';'
;
statement_list : /* empty */
{ $$ = 0; }
| statement_or_error
| statement_list NEWLINE
| statement_list NEWLINE statement_or_error
| statement_list ';'
| statement_list ';' statement
;
statement_or_error : statement
| error statement
{ $$ = $2; }
;
statement : Warranty
{ warranty (""); }
| Limits
{ limits (); }
| expression
{
if ($1 & 2)
warn ("comparison in expression");
if ($1 & 1)
generate ("W");
else
generate ("p");
}
| STRING
{
$$ = 0;
generate ("w");
generate ($1);
free ($1);
}
| Break
{
if (break_label == 0)
yyerror ("Break outside a for/while");
else
{
sprintf (genstr, "J%1d:", break_label);
generate (genstr);
}
}
| Continue
{
warn ("Continue statement");
if (continue_label == 0)
yyerror ("Continue outside a for");
else
{
sprintf (genstr, "J%1d:", continue_label);
generate (genstr);
}
}
| Quit
{ exit (0); }
| Halt
{ generate ("h"); }
| Return
{ generate ("0R"); }
| Return '(' return_expression ')'
{ generate ("R"); }
| For
{
$1 = break_label;
break_label = next_label++;
}
'(' opt_expression ';'
{
if ($4 > 1)
warn ("Comparison in first for expression");
$4 = next_label++;
if ($4 < 0)
sprintf (genstr, "N%1d:", $4);
else
sprintf (genstr, "pN%1d:", $4);
generate (genstr);
}
opt_expression ';'
{
if ($7 < 0) generate ("1");
$7 = next_label++;
sprintf (genstr, "B%1d:J%1d:", $7, break_label);
generate (genstr);
$<i_value>$ = continue_label;
continue_label = next_label++;
sprintf (genstr, "N%1d:", continue_label);
generate (genstr);
}
opt_expression ')'
{
if ($10 > 1)
warn ("Comparison in third for expression");
if ($10 < 0)
sprintf (genstr, "J%1d:N%1d:", $4, $7);
else
sprintf (genstr, "pJ%1d:N%1d:", $4, $7);
generate (genstr);
}
statement
{
sprintf (genstr, "J%1d:N%1d:",
continue_label, break_label);
generate (genstr);
break_label = $1;
continue_label = $<i_value>9;
}
| If '(' expression ')'
{
$3 = if_label;
if_label = next_label++;
sprintf (genstr, "Z%1d:", if_label);
generate (genstr);
}
statement opt_else
{
sprintf (genstr, "N%1d:", if_label);
generate (genstr);
if_label = $3;
}
| While
{
$1 = next_label++;
sprintf (genstr, "N%1d:", $1);
generate (genstr);
}
'(' expression
{
$4 = break_label;
break_label = next_label++;
sprintf (genstr, "Z%1d:", break_label);
generate (genstr);
}
')' statement
{
sprintf (genstr, "J%1d:N%1d:", $1, break_label);
generate (genstr);
break_label = $4;
}
| '{' statement_list '}'
{ $$ = 0; }
| Print
{ warn ("print statement"); }
print_list
;
print_list : print_element
| print_element ',' print_list
;
print_element : STRING
{
generate ("O");
generate ($1);
free ($1);
}
| expression
{ generate ("P"); }
;
opt_else : /* nothing */
| Else
{
warn ("else clause in if statement");
$1 = next_label++;
sprintf (genstr, "J%d:N%1d:", $1, if_label);
generate (genstr);
if_label = $1;
}
statement
function : Define NAME '(' opt_parameter_list ')' '{'
NEWLINE opt_auto_define_list
{
/* Check auto list against parameter list? */
check_params ($4,$8);
sprintf (genstr, "F%d,%s.%s[", lookup($2,FUNCT),
arg_str ($4,TRUE), arg_str ($8,TRUE));
generate (genstr);
free_args ($4);
free_args ($8);
$1 = next_label;
next_label = 0;
}
statement_list NEWLINE '}'
{
generate ("0R]");
next_label = $1;
}
;
opt_parameter_list : /* empty */
{ $$ = NULL; }
| define_list
;
opt_auto_define_list : /* empty */
{ $$ = NULL; }
| Auto define_list NEWLINE
{ $$ = $2; }
| Auto define_list ';'
{ $$ = $2; }
;
define_list : NAME
{ $$ = nextarg (NULL, lookup ($1,SIMPLE)); }
| NAME '[' ']'
{ $$ = nextarg (NULL, lookup ($1,ARRAY)); }
| define_list ',' NAME
{ $$ = nextarg ($1, lookup ($3,SIMPLE)); }
| define_list ',' NAME '[' ']'
{ $$ = nextarg ($1, lookup ($3,ARRAY)); }
;
opt_argument_list : /* empty */
{ $$ = NULL; }
| argument_list
;
argument_list : expression
{
if ($1 > 1) warn ("comparison in argument");
$$ = nextarg (NULL,0);
}
| NAME '[' ']'
{
sprintf (genstr, "K%d:", -lookup ($1,ARRAY));
generate (genstr);
$$ = nextarg (NULL,1);
}
| argument_list ',' expression
{
if ($3 > 1) warn ("comparison in argument");
$$ = nextarg ($1,0);
}
| argument_list ',' NAME '[' ']'
{
sprintf (genstr, "K%d:", -lookup ($3,ARRAY));
generate (genstr);
$$ = nextarg ($1,1);
}
;
opt_expression : /* empty */
{
$$ = -1;
warn ("Missing expression in for statement");
}
| expression
;
return_expression : /* empty */
{
$$ = 0;
generate ("0");
}
| expression
{
if ($1 > 1)
warn ("comparison in return expresion");
}
;
expression : named_expression ASSIGN_OP
{
if ($2 != '=')
{
if ($1 < 0)
sprintf (genstr, "DL%d:", -$1);
else
sprintf (genstr, "l%d:", $1);
generate (genstr);
}
}
expression
{
if ($4 > 1) warn("comparison in assignment");
if ($2 != '=')
{
sprintf (genstr, "%c", $2);
generate (genstr);
}
if ($1 < 0)
sprintf (genstr, "S%d:", -$1);
else
sprintf (genstr, "s%d:", $1);
generate (genstr);
$$ = 0;
}
;
| expression AND
{
warn("&& operator");
$2 = next_label++;
sprintf (genstr, "DZ%d:p", $2);
generate (genstr);
}
expression
{
sprintf (genstr, "DZ%d:p1N%d:", $2, $2);
generate (genstr);
$$ = $1 | $4;
}
| expression OR
{
warn("|| operator");
$2 = next_label++;
sprintf (genstr, "B%d:", $2);
generate (genstr);
}
expression
{
int tmplab;
tmplab = next_label++;
sprintf (genstr, "B%d:0J%d:N%d:1N%d:",
$2, tmplab, $2, tmplab);
generate (genstr);
$$ = $1 | $4;
}
| NOT expression
{
$$ = $2;
warn("! operator");
generate ("!");
}
| expression REL_OP expression
{
$$ = 3;
switch (*($2))
{
case '=':
generate ("=");
break;
case '!':
generate ("#");
break;
case '<':
if ($2[1] == '=')
generate ("{");
else
generate ("<");
break;
case '>':
if ($2[1] == '=')
generate ("}");
else
generate (">");
break;
}
}
| expression '+' expression
{
generate ("+");
$$ = $1 | $3;
}
| expression '-' expression
{
generate ("-");
$$ = $1 | $3;
}
| expression MUL_OP expression
{
genstr[0] = $2;
genstr[1] = 0;
generate (genstr);
$$ = $1 | $3;
}
| expression '^' expression
{
generate ("^");
$$ = $1 | $3;
}
| '-' expression %prec UNARY_MINUS
{
generate ("n");
$$ = $2;
}
| named_expression
{
$$ = 1;
if ($1 < 0)
sprintf (genstr, "L%d:", -$1);
else
sprintf (genstr, "l%d:", $1);
generate (genstr);
}
| NUMBER
{
int len = strlen($1);
$$ = 1;
if (len == 1 && *$1 == '0')
generate ("0");
else if (len == 1 && *$1 == '1')
generate ("1");
else
{
generate ("K");
generate ($1);
generate (":");
}
free ($1);
}
| '(' expression ')'
{ $$ = $2 | 1; }
| NAME '(' opt_argument_list ')'
{
$$ = 1;
if ($3 != NULL)
{
sprintf (genstr, "C%d,%s:",
lookup ($1,FUNCT),
arg_str ($3,FALSE));
free_args ($3);
}
else
{
sprintf (genstr, "C%d:", lookup ($1,FUNCT));
}
generate (genstr);
}
| INCR_DECR named_expression
{
$$ = 1;
if ($2 < 0)
{
if ($1 == '+')
sprintf (genstr, "DA%d:L%d:", -$2, -$2);
else
sprintf (genstr, "DM%d:L%d:", -$2, -$2);
}
else
{
if ($1 == '+')
sprintf (genstr, "i%d:l%d:", $2, $2);
else
sprintf (genstr, "d%d:l%d:", $2, $2);
}
generate (genstr);
}
| named_expression INCR_DECR
{
$$ = 1;
if ($1 < 0)
{
sprintf (genstr, "DL%d:x", -$1);
generate (genstr);
if ($2 == '+')
sprintf (genstr, "A%d:", -$1);
else
sprintf (genstr, "M%d:", -$1);
}
else
{
sprintf (genstr, "l%d:", $1);
generate (genstr);
if ($2 == '+')
sprintf (genstr, "i%d:", $1);
else
sprintf (genstr, "d%d:", $1);
}
generate (genstr);
}
| Length '(' expression ')'
{ generate ("cL"); $$ = 1;}
| Sqrt '(' expression ')'
{ generate ("cR"); $$ = 1;}
| Scale '(' expression ')'
{ generate ("cS"); $$ = 1;}
| Read '(' ')'
{
warn ("read function");
generate ("cI"); $$ = 1;
}
;
named_expression : NAME
{ $$ = lookup($1,SIMPLE); }
| NAME '[' expression ']'
{
if ($3 > 1) warn("comparison in subscript");
$$ = lookup($1,ARRAY);
}
| Ibase
{ $$ = 0; }
| Obase
{ $$ = 1; }
| Scale
{ $$ = 2; }
| Last
{ $$ = 3; }
;
%%

View File

@@ -1,154 +0,0 @@
/* bcdefs.h: The single file to include all constants and type definitions. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
/* Include the configuration file. */
#include "config.h"
/* Standard includes for all files. */
#include <stdio.h>
#include <sys/types.h>
#include <ctype.h>
#ifdef STRINGS_H
#include <strings.h>
#else
#include <string.h>
#endif
#ifndef NO_LIMITS
#include <limits.h>
#endif
/* Include the other definitions. */
#include "const.h"
#include "number.h"
/* These definitions define all the structures used in
code and data storage. This includes the representation of
labels. The "guiding" principle is to make structures that
take a minimum of space when unused but can be built to contain
the full structures. */
/* Labels are first. Labels are generated sequentially in functions
and full code. They just "point" to a single bye in the code. The
"address" is the byte number. The byte number is used to get an
actual character pointer. */
typedef struct bc_label_group
{
long l_adrs [ BC_LABEL_GROUP ];
struct bc_label_group *l_next;
} bc_label_group;
/* Each function has its own code segments and labels. There can be
no jumps between functions so labels are unique to a function. */
typedef struct arg_list
{
int av_name;
struct arg_list *next;
} arg_list;
typedef struct
{
char f_defined; /* Is this function defined yet. */
char *f_body[BC_MAX_SEGS];
int f_code_size;
bc_label_group *f_label;
arg_list *f_params;
arg_list *f_autos;
} bc_function;
/* Code addresses. */
typedef struct {
int pc_func;
int pc_addr;
} program_counter;
/* Variables are "pushable" (auto) and thus we need a stack mechanism.
This is built into the variable record. */
typedef struct bc_var
{
bc_num v_value;
struct bc_var *v_next;
} bc_var;
/* bc arrays can also be "auto" variables and thus need the same
kind of stacking mechanisms. */
typedef struct bc_array_node
{
union
{
bc_num n_num [NODE_SIZE];
struct bc_array_node *n_down [NODE_SIZE];
} n_items;
} bc_array_node;
typedef struct bc_array
{
bc_array_node *a_tree;
short a_depth;
} bc_array;
typedef struct bc_var_array
{
bc_array *a_value;
char a_param;
struct bc_var_array *a_next;
} bc_var_array;
/* For the stacks, execution and function, we need records to allow
for arbitrary size. */
typedef struct estack_rec {
bc_num s_num;
struct estack_rec *s_next;
} estack_rec;
typedef struct fstack_rec {
int s_val;
struct fstack_rec *s_next;
} fstack_rec;
/* The following are for the name tree. */
typedef struct id_rec {
char *id; /* The program name. */
/* A name == 0 => nothing assigned yet. */
int a_name; /* The array variable name (number). */
int f_name; /* The function name (number). */
int v_name; /* The variable name (number). */
short balance; /* For the balanced tree. */
struct id_rec *left, *right; /* Tree pointers. */
} id_rec;

View File

@@ -1,3 +0,0 @@
#!/bin/sh
make clean
make && make install

View File

@@ -1,4 +0,0 @@
/* config.h */
#define SMALL_BUF
#define BC_MATH_FILE "/usr/lib/libmath.b"
#define SHORTNAMES

View File

@@ -1,87 +0,0 @@
/* const.h: Constants for bc. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
/* Define INT_MAX and LONG_MAX if not defined. Assuming 32 bits... */
#ifdef NO_LIMITS
#define INT_MAX 0x7FFFFFFF
#define LONG_MAX 0x7FFFFFFF
#endif
/* Define constants in some reasonable size. The next 4 constants are
POSIX constants. */
#define BC_BASE_MAX INT_MAX
#define BC_SCALE_MAX INT_MAX
#define BC_STRING_MAX INT_MAX
/* Definitions for arrays. */
#define BC_DIM_MAX 65535 /* this should be NODE_SIZE^NODE_DEPTH-1 */
#define NODE_SIZE 16 /* Must be a power of 2. */
#define NODE_MASK 0xf /* Must be NODE_SIZE-1. */
#define NODE_SHIFT 4 /* Number of 1 bits in NODE_MASK. */
#define NODE_DEPTH 4
/* Other BC limits defined but not part of POSIX. */
#define BC_LABEL_GROUP 64
#define BC_LABEL_LOG 6
#define BC_MAX_SEGS 16 /* Code segments. */
#define BC_SEG_SIZE 1024
#define BC_SEG_LOG 10
/* Maximum number of variables, arrays and functions and the
allocation increment for the dynamic arrays. */
#define MAX_STORE 32767
#define STORE_INCR 32
/* Other interesting constants. */
#define FALSE 0
#define TRUE 1
#define SIMPLE 0
#define ARRAY 1
#define FUNCT 2
#define EXTERN extern
#ifdef __STDC__
#define CONST const
#define VOID void
#else
#define CONST
#define VOID
#endif
/* Include the version definition. */
#include "version.h"

View File

@@ -1,783 +0,0 @@
/* execute.c - run a bc program. */
/* This file is part of bc written for MINIX.
Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License , or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
You may contact the author by:
e-mail: phil@cs.wwu.edu
us-mail: Philip A. Nelson
Computer Science Department, 9062
Western Washington University
Bellingham, WA 98226-9062
*************************************************************************/
#include "bcdefs.h"
#include <signal.h>
#include "global.h"
#include "proto.h"
/* The SIGINT interrupt handling routine. */
int had_sigint;
void
stop_execution (sig)
int sig;
{
had_sigint = TRUE;
printf ("\n");
rt_error ("interrupted execution");
}
/* Get the current byte and advance the PC counter. */
unsigned char
byte (pc)
program_counter *pc;
{
int seg, offset;
seg = pc->pc_addr >> BC_SEG_LOG;
offset = pc->pc_addr++ % BC_SEG_SIZE;
return (functions[pc->pc_func].f_body[seg][offset]);
}
/* The routine that actually runs the machine. */
void
execute ()
{
int label_num, l_gp, l_off;
bc_label_group *gp;
char inst, ch;
int new_func;
int var_name;
int const_base;
bc_num temp_num;
arg_list *auto_list;
/* Initialize this run... */
pc.pc_func = 0;
pc.pc_addr = 0;
runtime_error = FALSE;
init_num (&temp_num);
/* Set up the interrupt mechanism for an interactive session. */
if (interactive)
{
signal (SIGINT, stop_execution);
had_sigint = FALSE;
}
while (pc.pc_addr < functions[pc.pc_func].f_code_size && !runtime_error)
{
inst = byte(&pc);
#if DEBUG > 3
{ /* Print out address and the stack before each instruction.*/
int depth; estack_rec *temp = ex_stack;
printf ("func=%d addr=%d inst=%c\n",pc.pc_func, pc.pc_addr, inst);
if (temp == NULL) printf ("empty stack.\n", inst);
else
{
depth = 1;
while (temp != NULL)
{
printf (" %d = ", depth);
out_num (temp->s_num, 10, out_char);
depth++;
temp = temp->s_next;
}
}
}
#endif
switch ( inst )
{
case 'A' : /* increment array variable (Add one). */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
incr_array (var_name);
break;
case 'B' : /* Branch to a label if TOS != 0. Remove value on TOS. */
case 'Z' : /* Branch to a label if TOS == 0. Remove value on TOS. */
c_code = !is_zero (ex_stack->s_num);
pop ();
case 'J' : /* Jump to a label. */
label_num = byte(&pc); /* Low order bits first. */
label_num += byte(&pc) << 8;
if (inst == 'J' || (inst == 'B' && c_code)
|| (inst == 'Z' && !c_code)) {
gp = functions[pc.pc_func].f_label;
l_gp = label_num >> BC_LABEL_LOG;
l_off = label_num % BC_LABEL_GROUP;
while (l_gp-- > 0) gp = gp->l_next;
pc.pc_addr = gp->l_adrs[l_off];
}
break;
case 'C' : /* Call a function. */
/* Get the function number. */
new_func = byte(&pc);
if ((new_func & 0x80) != 0)
new_func = ((new_func << 8) & 0x7f) + byte(&pc);
/* Check to make sure it is defined. */
if (!functions[new_func].f_defined)
{
rt_error ("Function %s not defined.", f_names[new_func]);
break;
}
/* Check and push parameters. */
process_params (&pc, new_func);
/* Push auto variables. */
for (auto_list = functions[new_func].f_autos;
auto_list != NULL;
auto_list = auto_list->next)
auto_var (auto_list->av_name);
/* Push pc and ibase. */
fpush (pc.pc_func);
fpush (pc.pc_addr);
fpush (i_base);
/* Reset pc to start of function. */
pc.pc_func = new_func;
pc.pc_addr = 0;
break;
case 'D' : /* Duplicate top of stack */
push_copy (ex_stack->s_num);
break;
case 'K' : /* Push a constant */
/* Get the input base and convert it to a bc number. */
if (pc.pc_func == 0)
const_base = i_base;
else
const_base = fn_stack->s_val;
if (const_base == 10)
push_b10_const (&pc);
else
push_constant (prog_char, const_base);
break;
case 'L' : /* load array variable */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
load_array (var_name);
break;
case 'M' : /* decrement array variable (Minus!) */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
decr_array (var_name);
break;
case 'O' : /* Write a string to the output with processing. */
while ((ch = byte(&pc)) != '"')
if (ch != '\\')
out_char (ch);
else
{
ch = byte(&pc);
if (ch == '"') break;
switch (ch)
{
case 'n': out_char ('\n'); break;
case 't': out_char ('\t'); break;
case 'r': out_char ('\r'); break;
case 'b': out_char (007); break;
case 'f': out_char ('\f'); break;
case '\\': out_char ('\\'); break;
default: break;
}
}
if (interactive) fflush (stdout);
break;
case 'R' : /* Return from function */
if (pc.pc_func != 0)
{
/* "Pop" autos and parameters. */
pop_vars(functions[pc.pc_func].f_autos);
pop_vars(functions[pc.pc_func].f_params);
/* reset the pc. */
fpop ();
pc.pc_addr = fpop ();
pc.pc_func = fpop ();
}
else
rt_error ("Return from main program.");
break;
case 'S' : /* store array variable */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
store_array (var_name);
break;
case 'T' : /* Test tos for zero */
c_code = is_zero (ex_stack->s_num);
assign (c_code);
break;
case 'W' : /* Write the value on the top of the stack. */
case 'P' : /* Write the value on the top of the stack. No newline. */
out_num (ex_stack->s_num, o_base, out_char);
if (inst == 'W') out_char ('\n');
store_var (3); /* Special variable "last". */
if (interactive) fflush (stdout);
break;
case 'c' : /* Call special function. */
new_func = byte(&pc);
switch (new_func)
{
case 'L': /* Length function. */
/* For the number 0.xxxx, 0 is not significant. */
if (ex_stack->s_num->n_len == 1 &&
ex_stack->s_num->n_scale != 0 &&
ex_stack->s_num->n_value[0] == 0 )
int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);
else
int2num (&ex_stack->s_num, ex_stack->s_num->n_len
+ ex_stack->s_num->n_scale);
break;
case 'S': /* Scale function. */
int2num (&ex_stack->s_num, ex_stack->s_num->n_scale);
break;
case 'R': /* Square Root function. */
if (!bc_sqrt (&ex_stack->s_num, scale))
rt_error ("Square root of a negative number");
break;
case 'I': /* Read function. */
push_constant (input_char, i_base);
break;
}
break;
case 'd' : /* Decrement number */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
decr_var (var_name);
break;
case 'h' : /* Halt the machine. */
exit (0);
case 'i' : /* increment number */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
incr_var (var_name);
break;
case 'l' : /* load variable */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
load_var (var_name);
break;
case 'n' : /* Negate top of stack. */
bc_sub (_zero_, ex_stack->s_num, &ex_stack->s_num);
break;
case 'p' : /* Pop the execution stack. */
pop ();
break;
case 's' : /* store variable */
var_name = byte(&pc);
if ((var_name & 0x80) != 0)
var_name = ((var_name << 8) & 0x7f) + byte(&pc);
store_var (var_name);
break;
case 'w' : /* Write a string to the output. */
while ((ch = byte(&pc)) != '"') out_char (ch);
if (interactive) fflush (stdout);
break;
case 'x' : /* Exchange Top of Stack with the one under the tos. */
if (check_stack(2)) {
bc_num temp = ex_stack->s_num;
ex_stack->s_num = ex_stack->s_next->s_num;
ex_stack->s_next->s_num = temp;
}
break;
case '0' : /* Load Constant 0. */
push_copy (_zero_);
break;
case '1' : /* Load Constant 0. */
push_copy (_one_);
break;
case '!' : /* Negate the boolean value on top of the stack. */
c_code = is_zero (ex_stack->s_num);
assign (c_code);
break;
case '&' : /* compare greater than */
if (check_stack(2))
{
c_code = !is_zero (ex_stack->s_next->s_num)
&& !is_zero (ex_stack->s_num);
pop ();
assign (c_code);
}
break;
case '|' : /* compare greater than */
if (check_stack(2))
{
c_code = !is_zero (ex_stack->s_next->s_num)
|| !is_zero (ex_stack->s_num);
pop ();
assign (c_code);
}
break;
case '+' : /* add */
if (check_stack(2))
{
bc_add (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num);
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
break;
case '-' : /* subtract */
if (check_stack(2))
{
bc_sub (ex_stack->s_next->s_num, ex_stack->s_num, &temp_num);
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
break;
case '*' : /* multiply */
if (check_stack(2))
{
bc_multiply (ex_stack->s_next->s_num, ex_stack->s_num,
&temp_num, scale);
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
break;
case '/' : /* divide */
if (check_stack(2))
{
if (bc_divide (ex_stack->s_next->s_num,
ex_stack->s_num, &temp_num, scale) == 0)
{
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
else
rt_error ("Divide by zero");
}
break;
case '%' : /* remainder */
if (check_stack(2))
{
if (is_zero (ex_stack->s_num))
rt_error ("Modulo by zero");
else
{
bc_modulo (ex_stack->s_next->s_num,
ex_stack->s_num, &temp_num, scale);
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
}
break;
case '^' : /* raise */
if (check_stack(2))
{
bc_raise (ex_stack->s_next->s_num,
ex_stack->s_num, &temp_num, scale);
if (is_zero (ex_stack->s_next->s_num) && is_neg (ex_stack->s_num))
rt_error ("divide by zero");
pop();
pop();
push_num (temp_num);
init_num (&temp_num);
}
break;
case '=' : /* compare equal */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) == 0;
pop ();
assign (c_code);
}
break;
case '#' : /* compare not equal */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) != 0;
pop ();
assign (c_code);
}
break;
case '<' : /* compare less than */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) == -1;
pop ();
assign (c_code);
}
break;
case '{' : /* compare less than or equal */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) <= 0;
pop ();
assign (c_code);
}
break;
case '>' : /* compare greater than */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) == 1;
pop ();
assign (c_code);
}
break;
case '}' : /* compare greater than or equal */
if (check_stack(2))
{
c_code = bc_compare (ex_stack->s_next->s_num,
ex_stack->s_num) >= 0;
pop ();
assign (c_code);
}
break;
default : /* error! */
rt_error ("bad instruction: inst=%c", inst);
}
}
/* Clean up the function stack and pop all autos/parameters. */
while (pc.pc_func != 0)
{
pop_vars(functions[pc.pc_func].f_autos);
pop_vars(functions[pc.pc_func].f_params);
fpop ();
pc.pc_addr = fpop ();
pc.pc_func = fpop ();
}
/* Clean up the execution stack. */
while (ex_stack != NULL) pop();
/* Clean up the interrupt stuff. */
if (interactive)
{
signal (SIGINT, use_quit);
if (had_sigint)
printf ("Interruption completed.\n");
}
}
/* Prog_char gets another byte from the program. It is used for
conversion of text constants in the code to numbers. */
char
prog_char ()
{
return byte(&pc);
}
/* Read a character from the standard input. This function is used
by the "read" function. */
char
input_char ()
{
char in_ch;
/* Get a character from the standard input for the read function. */
in_ch = getchar();
/* Check for a \ quoted newline. */
if (in_ch == '\\')
{
in_ch = getchar();
if (in_ch == '\n')
in_ch = getchar();
}
/* Classify and preprocess the input character. */
if (isdigit(in_ch))
return (in_ch - '0');
if (in_ch >= 'A' && in_ch <= 'F')
return (in_ch + 10 - 'A');
if (in_ch >= 'a' && in_ch <= 'f')
return (in_ch + 10 - 'a');
if (in_ch == '.' || in_ch == '+' || in_ch == '-')
return (in_ch);
if (in_ch <= ' ')
return (' ');
return (':');
}
/* Push_constant converts a sequence of input characters as returned
by IN_CHAR into a number. The number is pushed onto the execution
stack. The number is converted as a number in base CONV_BASE. */
void
push_constant (in_char, conv_base)
char (*in_char)(VOID);
int conv_base;
{
int digits;
bc_num build, temp, result, mult, divisor;
char in_ch, first_ch;
char negative;
/* Initialize all bc numbers */
init_num (&temp);
init_num (&result);
init_num (&mult);
build = copy_num (_zero_);
negative = FALSE;
/* The conversion base. */
int2num (&mult, conv_base);
/* Get things ready. */
in_ch = in_char();
while (in_ch == ' ')
in_ch = in_char();
if (in_ch == '+')
in_ch = in_char();
else
if (in_ch == '-')
{
negative = TRUE;
in_ch = in_char();
}
/* Check for the special case of a single digit. */
if (in_ch < 16)
{
first_ch = in_ch;
in_ch = in_char();
if (in_ch < 16 && first_ch >= conv_base)
first_ch = conv_base - 1;
int2num (&build, (int) first_ch);
}
/* Convert the integer part. */
while (in_ch < 16)
{
if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1;
bc_multiply (build, mult, &result, 0);
int2num (&temp, (int) in_ch);
bc_add (result, temp, &build);
in_ch = in_char();
}
if (in_ch == '.')
{
in_ch = in_char();
if (in_ch >= conv_base) in_ch = conv_base-1;
free_num (&result);
free_num (&temp);
divisor = copy_num (_one_);
result = copy_num (_zero_);
digits = 0;
while (in_ch < 16)
{
bc_multiply (result, mult, &result, 0);
int2num (&temp, (int) in_ch);
bc_add (result, temp, &result);
bc_multiply (divisor, mult, &divisor, 0);
digits++;
in_ch = in_char();
if (in_ch < 16 && in_ch >= conv_base) in_ch = conv_base-1;
}
bc_divide (result, divisor, &result, digits);
bc_add (build, result, &build);
}
/* Final work. */
if (negative)
bc_sub (_zero_, build, &build);
push_num (build);
free_num (&temp);
free_num (&result);
free_num (&mult);
}
/* When converting base 10 constants from the program, we use this
more efficient way to convert them to numbers. PC tells where
the constant starts and is expected to be advanced to after
the constant. */
void
push_b10_const (pc)
program_counter *pc;
{
bc_num build;
program_counter look_pc;
int kdigits, kscale;
char inchar;
char *ptr;
/* Count the digits and get things ready. */
look_pc = *pc;
kdigits = 0;
kscale = 0;
inchar = byte (&look_pc);
while (inchar != '.' && inchar != ':')
{
kdigits++;
inchar = byte(&look_pc);
}
if (inchar == '.' )
{
inchar = byte(&look_pc);
while (inchar != ':')
{
kscale++;
inchar = byte(&look_pc);
}
}
/* Get the first character again and move the pc. */
inchar = byte(pc);
/* Secial cases of 0, 1, and A-F single inputs. */
if (kdigits == 1 && kscale == 0)
{
if (inchar == 0)
{
push_copy (_zero_);
inchar = byte(pc);
return;
}
if (inchar == 1) {
push_copy (_one_);
inchar = byte(pc);
return;
}
if (inchar > 9)
{
init_num (&build);
int2num (&build, inchar);
push_num (build);
inchar = byte(pc);
return;
}
}
/* Build the new number. */
if (kdigits == 0)
{
build = new_num (1,kscale);
ptr = build->n_value;
*ptr++ = 0;
}
else
{
build = new_num (kdigits,kscale);
ptr = build->n_value;
}
while (inchar != ':')
{
if (inchar != '.')
if (inchar > 9)
*ptr++ = 9;
else
*ptr++ = inchar;
inchar = byte(pc);
}
push_num (build);
}
/* Put the correct value on the stack for C_CODE. Frees TOS num. */
void
assign (c_code)
char c_code;
{
free_num (&ex_stack->s_num);
if (c_code)
ex_stack->s_num = copy_num (_one_);
else
ex_stack->s_num = copy_num (_zero_);
}

Some files were not shown because too many files have changed in this diff Show More