home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / emacs-18.59-src.tgz / emacs-18.59-src.tar / fsf / emacs18 / amiga / unix / unix.doc < prev   
Text File  |  1996-09-28  |  18KB  |  453 lines

  1. Unix compatibility library for SAS C 6.x version 1.2
  2. ----------------------------------------------------
  3.  
  4. Introduction
  5. ------------
  6.  
  7. This library provides 80 odd functions which are useful for porting
  8. Unix programs to the Amiga running AmigaOS 2.04 or higher. It is thus
  9. similar to Markus Wild's ixemul.library, but has more restricted aims:
  10.  
  11. a) It is written specifically for SAS C 6.1, 6.2, ...
  12.  
  13. b) It isn't a complete C library, it requires the SAS C library to function.
  14. It adds some routines, and replaces others that were deficient, out of date,
  15. or that didn't provide adequate functionality.
  16.  
  17. c) It isn't a complete Unix emulation library, it only contains those functions
  18. that I needed while porting various utilities (mainly from GNU) to the Amiga.
  19.  
  20. d) It is a traditional C link library, not an Amiga library. This produces 
  21. bigger executables.
  22.  
  23. Considering the above points, you might ask why I wrote it ... There are several
  24. good answers:
  25.  
  26. a) I started it before I was aware of ixemul.library.
  27.  
  28. b) ixemul.library didn't provide the features I needed for Emacs (support for
  29. select).
  30.  
  31. c) It is easier for me to maintain when I find I need to support another Unix
  32. feature (eg deleting open files).
  33.  
  34. Copying
  35. -------
  36.  
  37. The library includes code that I have written, which I place in the public domain.
  38. This is found in all the files that don't have a Copyright notice.
  39.  
  40. It also includes code which is (inclusive of my modifications)
  41.  
  42.  Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
  43.  All rights reserved.
  44.  
  45. This code is freely redistributable (see the copyright notices in the source
  46. and include files).
  47.  
  48. Finally it includes Doug Gwyn's public domain alloca implementation.
  49.  
  50. Installation & Use
  51. ------------------
  52.  
  53. To use this library, you must compile with the include directory in your include
  54. search path, and link with the unix.lib library (which must be specified before
  55. lc.lib). For example, if you extract this archive in a directory called src:, you
  56. could compile the following program:
  57.  
  58. echo.c:
  59.  
  60. #include <sys/unistd.h>
  61.  
  62. void main(int argc, char **argv)
  63. {
  64.   int i;
  65.  
  66.   for (i = 1; i < argc; i++)
  67.     {
  68.       if (i != 1) write(1, " ", 1);
  69.       write(1, argv[i], strlen(argv[i]));
  70.     }
  71.   write(1, "\n", 1);
  72. }
  73.  
  74. with the command
  75.  
  76.   sc idir src:unix/include/ lib src:unix/src/unix.lib link echo.c
  77.  
  78. to produce a simple unix-like echo command.
  79.  
  80. You should define the following environment variables:
  81.  
  82. USER - A user name for the sole Amiga user (default "user").
  83. USERNAME - The full name of the sole Amiga user (default $USER).
  84. HOME - A "home" directory (default "s:") for programs that want one. Configuration
  85.        files will probably end up here ...
  86. SHELL - A program which behaves reasonably like a Unix shell (default "bin:sh").
  87.     You should copy the sh executable there if you don't have a Unix-like shell.
  88. HOSTNAME - The name of your machine (default "amiga").
  89.  
  90. If you are going to be using pipes, you will require Matt Dillon's fifo.library
  91. and fifo: device. This can be found on the Fish disks, with his UUCP distribution
  92. and on many FTP sites.
  93.  
  94. If you want to install the timezone information (see the discussion below on
  95. Unix vs Amiga time), do the following:
  96.  
  97.   a) change to the zoneinfo directory
  98.   b) compile the zic problem by running lmk.
  99.   c) change to the datfiles directory.
  100.   d) edit lmkfile and choose your timezone (you can look at the data files
  101.      to see the ones available). If you get this wrong, you can always change
  102.      it later with the zic program.
  103.   e) type 'lmk install'. This will compile the timezones, and setup the one
  104.      you chose as the default. The default can be changed with
  105.        zic -l <timezone name>
  106.  
  107.      or by defining the environment variable TZ.
  108.  
  109. Functionality
  110. -------------
  111.  
  112. While this library aims to hide the differences between AmigaOS & Unix, 
  113. it also aims to provide support for Amiga specific features. This sometimes
  114. produces strange compromises.
  115.  
  116. This library provides two things to programs linked with it:
  117.  
  118. a) A Unix-like environment:
  119.  
  120. This includes:
  121.  
  122. - Unix-like command line parsing, with wildcard expansion. These
  123. wildcards are however specified with the Amiga syntax. 
  124.  
  125. Arguments which are unquoted or surround with single quotes are
  126. handled like Unix shells. Those surrounded with double quotes are
  127. handled in the Amiga fashion, but with wildcard expansion (this is
  128. done to avoid problems with the way the exec function works).
  129.  
  130. Here is a summary of argument splitting:
  131.  
  132. Arguments can be enclosed in single quotes, (') double quotes ("), or 
  133. separated by spaces.
  134.  
  135. Arguments enclosed by single quotes never suffer wildcard expansion, and
  136. no character is significant inside them (not even \). Given the echo program
  137. given above,
  138.  
  139.   echo 'f*un\'
  140.  
  141. simply displays
  142.  
  143.   f*un\
  144.  
  145. Within double quotes, * is the standard Amiga escape character. \ is
  146. handled just like any other character. Wildcards are expanded. So,
  147. assuming the current directory contains only echo.c and echo,
  148.  
  149.   echo "#?.c" "*.c" "\mad"
  150.  
  151. displays
  152.  
  153.   echo.c .c \mad
  154.  
  155. (* escapes the following character, except that *N is newline and *E is 
  156. escape. Wildcard characters still behave as usual (' is the standard
  157. Amiga wildcard escape character)).
  158.  
  159. If an argument is unquoted, \ acts as an escape character (removing
  160. special significance from the next character, be it a wildcard, a space, 
  161. a \, ...). So
  162.  
  163.   echo \*.c \\ \n
  164.  
  165. displays
  166.  
  167.   *.c \ n
  168.  
  169. - When a program is run from the Workbench, stdin, stdout & stderr are opened 
  170. on NIL:, and the icons selected are converted to file names and passed as the
  171. argc,argv to main.
  172.  
  173. - The standard variable environ is defined and contains all the local environment
  174. variables. This is passed as the envp parameter to main.
  175.  
  176. - The program is led to believe that all files belong to $USER (uid 1), group
  177. wheel (gid 0).
  178.  
  179. - Amiga protection flags are mapped onto the standard 12 Unix protection bits
  180. (and back when necessary). This can be overridden (dynamically) by changing the
  181. value of use_amiga_flags. Eg:
  182.  
  183.   extern int use_amiga_flags;
  184.  
  185.   ...
  186.  
  187.  
  188.   main()
  189.   {
  190.     use_amiga_flags = 1;
  191.  
  192.     ... some code using stat or chmod or ...
  193.   }
  194.  
  195. In this case, the Amiga protection bits are left untouched. Otherwise the
  196. mapping is as follows (note that the archive bit is lost):
  197.  
  198. Unix -> Amiga
  199.  
  200. Amiga read: if user, group or world read.
  201. Amiga write: if user or group write.
  202. Amiga delete: if user or world write.
  203. Amiga execute: if group execute or only user execute.
  204. Amiga script: if world execute or only user execute.
  205. Amiga pure: if sticky.
  206.  
  207. Amiga -> Unix
  208.  
  209. user, group, world read: if amiga read.
  210. user write: if amiga write and delete.
  211. group write: if amiga write.
  212. world write: if amiga delete.
  213. user execute: if amiga execute or amiga script.
  214. group execute: if amiga execute.
  215. world execute: if amiga script.
  216. sticky: if amiga pure.
  217.  
  218. - Unix-like time. time is expressed in seconds since 1-Jan-1970 00:00 GMT. 
  219. This is the format used by the time(), stat() and utime() functions. The
  220. library uses the BSD time functions which properly handle timezones, 
  221. daylight savings time, etc. 
  222.  
  223. On Unix systems, time is generally stored as GMT, while the Amiga stores
  224. local time. These times are visible in two places: the time stored in the
  225. system clock and the creation, modification or access dates for files (only
  226. the modification date is available on the Amiga). There are 3 ways to resolve
  227. this conflict:
  228.  
  229. 1) Ignore timezones (you can choose this option by not installing the
  230. timezone information). The library will then assume that system time
  231. and file times are expressed in GMT and will never apply any
  232. corrections. All will work well (except maybe on a global network).
  233. This is the simplest solution.
  234.  
  235. 2) System & file time are assumed to be local times. The time() & stat()
  236. functions convert local time to GMT, the utime() call converts GMT to
  237. local time. This allows you to keep the system clock on local time, which
  238. is compatible with most (all?) Amiga applications. However, nearly every
  239. program will be bigger because they will need the timezone information and
  240. timezone conversion code (approximately 7k). The library can be recompiled
  241. if you prefer to have things this way by adding -dUSE_LOCAL to the CFLAGS
  242. variable in lmkfile.
  243.  
  244. 3) System & file time are stored in GMT. Times are converted to local time
  245. only when they are displayed to the user, who must of course choose the 
  246. correct timezone. This entails changing your system clock to GMT, which means
  247. that most programs will display an incorrect time. However, you won't have
  248. to change your system clock when daylight savings time ends ... The library
  249. comes compiled this way (But you can still choose option 1, no timezone
  250. information, and avoid the potential confusion).
  251.  
  252. - BSD-like signals. Signal handlers stay enabled after a signal occurs
  253. (that particular signal is simply masked for the duration of the handler).
  254. setjmp & longjmp preserve the signal mask (the functions _setjmp & _longjmp
  255. don't). You may receive any signal with kill(getpid(), sig). Otherwise only
  256. the following occur:
  257.  
  258.   SIGINT: user typed ctrl-c
  259.   SIGQUIT: user typed ctrl-d
  260.   SIGALRM: alarm() expired
  261.   SIGCHLD: a child process died
  262.  
  263. When using kill to signal another process, only SIGHUP, SIGINT, SIGQUIT & 
  264. SIGKILL do anything. They all send SIGBREAKF_CTRL_C | D to the process (and
  265. hopefully its children). See the discussion under the exec function.
  266.  
  267.  
  268. b) A large number of unix C library calls:
  269.  
  270. _exit, _setjmp, _longjmp, abort, access, alloca, gettimeofday, ftime, 
  271. bcmp, bcopy, bzero, chmod, chown, fchown, close, creat, tzset, tzsetwall,
  272. localtime, gmtime, asctime, ctime, mktime, opendir, closedir, readdir, 
  273. telldir, seekdir, fchmod, fcntl, fstat, ftruncate, getenv, gethostname,
  274. getpid, getwd, getgid, getegid, getgrgid, getgrnam, index, ioctl, isatty,
  275. kill, link, lseek, mkdir, mkfifo, mknod, mktemp, open, perror, pipe, sktpair, 
  276. getpwuid, getpwnam, getlogin, read, rename, rindex, rmdir, select, setjmp, 
  277. longjmp, signal, sigpause, sigsetmask, sleep, stat, strftime, time, truncate,
  278. getuid, geteuid, umask, unlink, utime, wait, waitpid, wait3, wait4, write,
  279. readlink, symlink, popen, pclose.
  280.  
  281. These functions aim to be BSD compatible, however I based myself on descriptions
  282. in the SunOS 4 man pages. Their behaviour is sometimes strange or incomplete.
  283.  
  284. Here is a summary of the differences with the standard Unix functions:
  285.  
  286. alloca - This is Doug Gwyn's portable alloca. Memory allocated is freed
  287. later than with a true alloca.
  288.  
  289. gettimeofday - The dst field of the timezone is a (not very good) guess. It
  290. shouldn't be used anyway.
  291.  
  292. chown, fchown - These are do-nothing routines.
  293.  
  294. opendir, closedir, ... - These interact with stat to avoid having to read
  295. each directory entry twice when doing a readdir + stat loop.
  296.  
  297. fchmod - The protection is only set when the file is closed. See also the
  298. discussion of protection modes above.
  299.  
  300. fcntl - Only the F_GETFL & F_SETFL operations are supported.
  301.  
  302. truncate, ftruncate - These will not necessarily work with all filing systems.
  303. See the discussion of the AmigaOS SetFileSize function.
  304.  
  305. getenv - This checks local environment variables and then global ones. It 
  306. allocates memory for the variables value each time. This memory is never freed
  307. (till the program exits).
  308.  
  309. gethostname - This is obtained from the HOSTNAME environment variable at startup.
  310.  
  311. getuid, geteuid, getgid, getegid, getpwuid, getpwnam, getgrgid, getgrnam, getlogin -
  312. These function only know about one user. He/She is:
  313.  
  314.   name: $USER (default "user")
  315.   home directory: $HOME (default "s:")
  316.   shell: $SHELL (default "bin:sh")
  317.   uid: 1, gid: 0
  318.  
  319. ioctl - Only FIONBIO & TIOCGWINSZ are known, plus a number of amiga specific
  320. ioctls (for internal use). These are documented in include/amiga/ioctl.h.
  321.  
  322. lseek - Seeks beyond the end of a file are not implemented.
  323.  
  324. mkfifo, mknod - These are 'do-nothing' routines.
  325.  
  326. pipe - This uses Matt Dillon's fifo.library and fifo: device. It works well
  327. for interactive use, but not for transfering large quantities of data.
  328.  
  329. select - This implementation only works with pipes & sktpairs, and cannot
  330. detect 'exceptional' conditions.
  331.  
  332. sigvec - The flags are not recognized.
  333.  
  334. symlink - Symbolic links on the Amiga are far too buggy and should not be used.
  335. By default, as compiled, this routine always returns an error. However readlink
  336. does work, so you can read existing symbolic links.
  337.  
  338. umask - This is a 'do-nothing' routine.
  339.  
  340. unlink - You can unlink a file that your program has opened before you close
  341. it. At that point, the AmigaOS file is closed & deleted, though it still
  342. appears open to read (it returns EOF), write, close, etc. Also you can unlink
  343. a file even if it is protected from deletion (the protection mode is changed
  344. first ...).
  345.  
  346. utime - Only the modification time can be changed (the others don't exist).
  347.  
  348. wait3, wait4 - Resource usage is never returned.
  349.  
  350. exec
  351. ----
  352.  
  353. vfork() and execxx() are very tricky to implement. So I took the easy
  354. (but see below) way out, providing a function, eexec, that create a
  355. new process given argc, argv.  This functions returns a pid which can
  356. be used with wait, waitpid, ... as usual. Also exiting processes
  357. generate the SIGCHLD signal. With this, it is generally fairly easy to
  358. replace the process creation parts of most Unix programs.
  359.  
  360. First, here is a description of the problems which arise:
  361.  
  362. Executing an external program is tricky with AmigaOS. The various system
  363. routines (CreateNewProc, SystemTags, Execute) allow some operations to be
  364. done easily, but make others difficult. Specifically, if you want to do all
  365. of the following:
  366.  
  367. - Execute a program given argc, argv (like with unix)
  368. - Specify arbitrary input, output and error streams, including inheriting
  369. the current ones.
  370. - Have some of these streams be pipes of which you keep one end.
  371. - Have some of these pipes appear to be interactive (this is used for example
  372. by programs running inside emacs).
  373. - Detect when the execute program exits, and get its return code.
  374. - Send signals (eg ctrl-c) to the created process, and preferably its children.
  375.  
  376. you are in deep trouble. A minimum of 10 attempts is needed to get
  377. something which works most of the time, ie the eexec function.
  378.  
  379. The problems are:
  380. - You have to make a command line from argc, argv. But these arguments may
  381. contain spaces, so they must be surrounded by double quotes. And then, '*'
  382. must be escaped as it is the escape character. And so on.
  383. - Only recently has an error stream appeared in AmigaOS. And it doesn't
  384. inherit very well (Indeed, specifying the error stream doesn't work in the
  385. current version).
  386. - Amiga programs generally expect interactive files to be console windows.
  387. And fifo: is the only interactive pipe I'm aware of. So the pipe: system
  388. call uses fifo: and fifo.library.
  389. - To get the return code of an application, you must use the synchronous
  390. version of SystemTags. Otherwise it is lost. But you want an asynchronous
  391. process facility. So I create 2 processes, the first one is created with
  392. CreateNewProc and executes a custom piece of code. This code launches
  393. the real program with SystemTags, and sends a message with the return code
  394. to its parent (if it is still around).
  395. - You can't find the children of a process. So the signal is sent to all
  396. the processes that share the input filehandle of the created process. This
  397. is the best solution that I found.
  398. - AmigaOS isn't Unix.
  399.  
  400. Therefore, the eexec function is far from perfect. It works as follows:
  401.  
  402. eexec(program, argv, input, output, error, directory, stacksize)
  403.  
  404.   program: the path of the executable file. Your path is searched.
  405.   argv: A null terminated array of arguments. The first (argv[0]) is ignored.
  406.   input: A unix filehandle on the desired input. -1 means copy Input().
  407.   output: A unix filehandle on the desired output. -1 means copy Output().
  408.   error: A unix filehandle on the desired error stream. -1 means copy the pr_CES
  409.      field of the current process, -2 means copy the value specified for output.
  410.          Currently, this parameter has no effect.
  411.   directory: pathname for the current directory for the created process, or NULL
  412.          to inheir the current processes'.
  413.   stacksize: stack size for the created process. 0 means the same size as the 
  414.          current stack.
  415.   
  416. _start_process is a lower level interface:
  417.  
  418. _start_process(command, input, close_input, output, close_output,
  419.            error, close_error, dir, stacksize)
  420.   command: the string to pass to SystemTags (it will be passed to
  421.     the UserShell, not the system default).
  422.   input, output, error, close_xxx: AmigaOS filehandles for use as the
  423.     appropriate stream. If close_x is true, the corresponding stream will be
  424.     closed when the process exits.
  425.   dir: Lock on the desired directory for the new process.
  426.   stacksize: as above.
  427.  
  428.  
  429. Recompiling
  430. -----------
  431.  
  432. To recompile, simply run lmk in the src directory. You can add the -dUSE_LOCAL
  433. flag to CFLAGS in lmkfile if you want the system clock to store local time 
  434. instead of GMT.
  435.  
  436. If you want symlink to work, add -dSOFTLINK to CFLAGS (For example, tar uses
  437. a version of unix.lib compiled like this).
  438.  
  439. If you add modules, you can use the mkmkf to remake the makefile dependencies
  440. (it generates lmkfile from lmkfile.base and the dependencies for all the .c
  441. files in the current directory). This program requires perl (available from
  442. ftp sites).
  443.  
  444.  
  445. Changes from 1.0 to 1.1
  446. -----------------------
  447. stat() now returns a value for st_dev.
  448. exec() extended by eexec, assembly part rewritten in C.
  449. symbolic links recognized. Their use is not recommended (too buggy).
  450. sigvec added.
  451. popen, pclose added.
  452. Documentation discusses exec.
  453.