Annotation of freem/src/init.c, revision 1.12
1.1 snw 1: /*
1.12 ! snw 2: * $Id: init.c,v 1.11 2025/04/13 04:22:43 snw Exp $
1.1 snw 3: * FreeM initialization
4: *
5: *
1.5 snw 6: * Author: Serena Willis <snw@coherent-logic.com>
1.1 snw 7: * Copyright (C) 1998 MUG Deutschland
1.6 snw 8: * Copyright (C) 2020, 2025 Coherent Logic Development LLC
1.1 snw 9: *
10: *
11: * This file is part of FreeM.
12: *
13: * FreeM is free software: you can redistribute it and/or modify
14: * it under the terms of the GNU Affero Public License as published by
15: * the Free Software Foundation, either version 3 of the License, or
16: * (at your option) any later version.
17: *
18: * FreeM is distributed in the hope that it will be useful,
19: * but WITHOUT ANY WARRANTY; without even the implied warranty of
20: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21: * GNU Affero Public License for more details.
22: *
23: * You should have received a copy of the GNU Affero Public License
24: * along with FreeM. If not, see <https://www.gnu.org/licenses/>.
25: *
1.7 snw 26: * $Log: init.c,v $
1.12 ! snw 27: * Revision 1.11 2025/04/13 04:22:43 snw
! 28: * Fix snprintf calls
! 29: *
1.11 snw 30: * Revision 1.10 2025/04/10 01:24:38 snw
31: * Remove C++ style comments
32: *
1.10 snw 33: * Revision 1.9 2025/04/03 16:58:34 snw
34: * Make error message for shm_init error during initialization more friendly
35: *
1.9 snw 36: * Revision 1.8 2025/03/24 04:44:55 snw
37: * Don't call ttyname on OS/2
38: *
1.8 snw 39: * Revision 1.7 2025/03/24 04:05:36 snw
40: * Replace crlf with frm_crlf to avoid symbol conflict with readline on OS/2
41: *
1.7 snw 42: * Revision 1.6 2025/03/09 19:14:25 snw
43: * First phase of REUSE compliance and header reformat
44: *
1.6 snw 45: *
46: * SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC
47: * SPDX-License-Identifier: AGPL-3.0-or-later
1.1 snw 48: **/
49:
50: #include <stdio.h>
51: #include <stdlib.h>
52: #include <string.h>
53: #include <unistd.h>
54: #include <limits.h>
55: #include <sys/types.h>
56: #include <sys/stat.h>
57: #include <pwd.h>
58: #include <time.h>
59: #include <errno.h>
60: #include <sys/ioctl.h>
1.2 snw 61:
1.4 snw 62: #if !defined(__APPLE__) && !defined(__gnu_hurd__) && !defined(EMSCRIPTEN)
63: # if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__AMIGA)
64: # include <termios.h>
65: # if !defined(__AMIGA)
66: # define TCGETA TIOCGETA
67: # define TCSETA TIOCSETA
68: # endif
69: # define termio termios
70: # else
71: # if !defined(MSDOS)
72: # include <termio.h>
73: # endif
74: # endif
1.2 snw 75: #else
76: # include <termios.h>
77: #endif
1.1 snw 78:
79: #include "config.h"
80:
81: #if defined(HAVE_MWAPI_MOTIF)
82: # include <Xm/Xm.h>
83: #endif
84:
85: #include "mpsdef.h"
86: #include "transact.h"
87: #include "namespace.h"
88: #include "events.h"
89: #include "mdebug.h"
90: #include "shmmgr.h"
91: #include "locktab.h"
92: #include "jobtab.h"
93: #include "datatypes.h"
94: #include "objects.h"
1.12 ! snw 95: #include "log.h"
1.1 snw 96:
97: #ifdef HAVE_LIBREADLINE
98: # if defined(HAVE_READLINE_READLINE_H)
99: # include <readline/readline.h>
100: # elif defined(HAVE_READLINE_H)
101: # include <readline.h>
102: # else /* !defined(HAVE_READLINE_H) */
103: extern char *readline ();
104: # endif /* !defined(HAVE_READLINE_H) */
105: char *cmdline = NULL;
106: #else /* !defined(HAVE_READLINE_READLINE_H) */
107: /* no readline */
108: #endif /* HAVE_LIBREADLINE */
109:
110: #ifdef HAVE_READLINE_HISTORY
111: # if defined(HAVE_READLINE_HISTORY_H)
112: # include <readline/history.h>
113: # elif defined(HAVE_HISTORY_H)
114: # include <history.h>
115: # else /* !defined(HAVE_HISTORY_H) */
116: extern void add_history ();
117: extern int write_history ();
118: extern int read_history ();
119: # endif /* defined(HAVE_READLINE_HISTORY_H) */
120: /* no history */
121: #endif /* HAVE_READLINE_HISTORY */
122:
123: #if defined(HAVE_WIRINGPI_H)
124: # include <wiringPi.h>
125: #endif
126:
127: #if !defined(PATH_MAX) && defined(_SCO_DS)
128: # define PATH_MAX 4096
129: #endif
130:
131: #if !defined(PATH_MAX) && defined(__gnu_hurd__)
132: # define PATH_MAX 1024
133: #endif
134:
135: #if !defined(PATH_MAX) && defined(__sun__)
136: # include <limits.h>
137: #endif
138:
139: #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__)
140: # include <sys/syslimits.h>
141: #endif
142:
143: #define SHMKEY 0x990120
144: #define SHMSIZ 1048576
145:
146: void init_process(void);
147: void init_devtable(void);
148: void init_signals(void);
149: void init_timezone(void);
150: void init_freem_path(void);
151:
152: #if defined(HAVE_LIBREADLINE)
153: void init_readline(void);
154: #endif
155:
156: void init_execution_context(void);
157: void init_io(void);
158: void init_random_number(void);
159: void init_ztrap(void);
160: void init_ssvn(void);
161: void init_terminal(void);
162: void init_estack(void);
163:
164: void init_mwapi(void);
165:
166: short init (char *namespace_name)
167: {
168: short retval;
1.12 ! snw 169:
! 170: init_log ();
1.1 snw 171: init_process ();
172: init_devtable ();
173: init_signals ();
174: init_freem_path ();
175: init_timezone ();
176:
177: #if defined(HAVE_LIBREADLINE)
178: init_readline ();
179: #endif
180:
181: init_execution_context ();
182:
183: if (run_daemon == FALSE) {
184: init_io ();
185: }
186:
187: init_random_number ();
188: init_ztrap ();
189:
190: retval = shm_init (shm_init_size);
191:
192: if (retval == SHMS_GET_ERR) {
1.9 snw 193: if (errno != 13) {
194: fprintf (stderr, "init: error initializing shared memory [errno %d]\r\n", errno);
195: }
196: else {
197: fprintf (stderr, "init: error attaching to environment -- does your user belong to the group that owns environment '%s'?\r\n", shm_env);
198: }
199: if (run_daemon == FALSE) {
200: set_io (UNIX);
201: }
1.1 snw 202: exit (1);
203: }
204:
205: symtab_init ();
206: tp_init ();
207:
208: set_namespace (namespace_name, FALSE);
209:
210: if (first_process) {
211: fprintf (stderr, "init: we are the first process in the environment (pid %d)\r\n", pid);
212: }
213:
214: if (first_process) fprintf (stderr, "init: initializing job table\r\n");
215: jobtab_init ();
216:
217: if (first_process) fprintf (stderr, "init: adding job to job table\r\n");
218: job_init (FALSE);
219:
220: if (first_process) fprintf (stderr, "init: initializing structured system variables\r\n");
221: init_ssvn ();
222:
223: if (first_process) fprintf (stderr, "init: initializing terminal\r\n");
224: init_terminal ();
225:
226: if (first_process) fprintf (stderr, "init: initializing asynchronous events\r\n");
227: evt_init ();
228:
229: if (first_process) fprintf (stderr, "init: initializing debugger\r\n");
230: dbg_init ();
231:
232: if (first_process) fprintf (stderr, "init: initializing error stack\r\n");
233: init_estack();
234:
235: etrap[0] = EOL;
236: ecode[0] = EOL;
237: estack = 0;
238:
239: init_mwapi();
240:
241: if (merr () == OK) {
242: return TRUE;
243: }
244:
245: return FALSE;
246: }
247:
248: void init_process (void)
249: {
250: pid = getpid (); /* get $J = process ID */
251: umask (0); /* protection bits mask to full rights */
1.11 snw 252: snprintf (fp_conversion, sizeof (fp_conversion) - 1, "%%.%df\201", DBL_DIG);
1.1 snw 253:
254: if (fp_mode) {
255: zprecise = DBL_DIG;
256: }
257: else {
258: zprecise = 100;
259: }
260: }
261:
262: void init_devtable (void)
263: {
264: register int i;
265: register int j;
266:
267: for (j = 0; j <= MAXDEV; j++) { /* init. translation tables */
268:
269: for (i = 0; i < 256; i++) {
270: G0I[j][i] = (char) i;
271: G0O[j][i] = (char) i;
272: G1I[j][i] = (char) i;
273: G1O[j][i] = (char) i;
274: }
275:
276: G0I[j][UNSIGN (EOL)] = NUL;
277: G0O[j][UNSIGN (EOL)] = NUL;
278: G1I[j][UNSIGN (EOL)] = NUL;
279: G1O[j][UNSIGN (EOL)] = NUL;
280: G0I[j][UNSIGN (DELIM)] = NUL;
281: G0O[j][UNSIGN (DELIM)] = NUL;
282: G1I[j][UNSIGN (DELIM)] = NUL;
283: G1O[j][UNSIGN (DELIM)] = NUL;
284: G0I[j][256] = EOL;
285: G0O[j][256] = EOL;
286: G1I[j][256] = EOL;
287: G1O[j][256] = EOL;
288:
289: }
290:
291: #ifdef SCO
292: #ifndef HACK_NOXLATE
293: G0I[HOME][245] = 64;
294: G0O[HOME][64] = 245; /* Paragraph */
295: G0I[HOME][142] = 91;
296: G0O[HOME][91] = 142; /* A umlaut */
297: G0I[HOME][153] = 92;
298: G0O[HOME][92] = 153; /* O umlaut */
299: G0I[HOME][154] = 93;
300: G0O[HOME][93] = 154; /* U umlaut */
301: G0I[HOME][132] = 123;
302: G0O[HOME][123] = 132; /* a umlaut */
303: G0I[HOME][148] = 124;
304: G0O[HOME][124] = 148; /* o umlaut */
305: G0I[HOME][129] = 125;
306: G0O[HOME][125] = 129; /* u umlaut */
307: G0I[HOME][225] = 126;
308: G0O[HOME][126] = 225; /* sharp s */
309: #endif/*HACK_NOXLATE*/
310:
311: /* DEC Special graphics */
312: G1I[HOME][254] = 96;
313: G1O[HOME][96] = 254; /* diamond */
314: G1I[HOME][176] = 97;
315: G1O[HOME][97] = 176; /* checker board */
316: G1I[HOME][241] = 99;
317: G1O[HOME][99] = 241; /* FF */
318: G1I[HOME][242] = 100;
319: G1O[HOME][100] = 242; /* CR */
320: G1I[HOME][243] = 101;
321: G1O[HOME][101] = 243; /* LF */
322: G1I[HOME][248] = 102;
323: G1O[HOME][102] = 248; /* degree sign */
324: G1I[HOME][241] = 103;
325: G1O[HOME][103] = 241; /* plus minus */
326: G1I[HOME][244] = 104;
327: G1O[HOME][104] = 244; /* NL */
328: G1I[HOME][251] = 105;
329: G1O[HOME][105] = 251; /* VT */
330: G1I[HOME][217] = 106;
331: G1O[HOME][106] = 217; /* lower right corner */
332: G1I[HOME][191] = 107;
333: G1O[HOME][107] = 191; /* upper right corner */
334: G1I[HOME][218] = 108;
335: G1O[HOME][108] = 218; /* upper left corner */
336: G1I[HOME][192] = 109;
337: G1O[HOME][109] = 192; /* lower left corner */
338: G1I[HOME][197] = 110;
339: G1O[HOME][110] = 197; /* cross */
340: G1I[HOME][200] = 111;
341: G1O[HOME][111] = 200; /* linescan 5 */
342: G1I[HOME][201] = 112;
343: G1O[HOME][112] = 201; /* linescan 4 */
344: G1I[HOME][196] = 113;
345: G1O[HOME][113] = 196; /* linescan 3 */
346: G1I[HOME][202] = 114;
347: G1O[HOME][114] = 202; /* linescan 2 */
348: G1I[HOME][203] = 115;
349: G1O[HOME][115] = 203; /* linescan 1 */
350: G1I[HOME][195] = 116;
351: G1O[HOME][116] = 195; /* left junction */
352: G1I[HOME][180] = 117;
353: G1O[HOME][117] = 180; /* right junction */
354: G1I[HOME][193] = 118;
355: G1O[HOME][118] = 193; /* lower junction */
356: G1I[HOME][194] = 119;
357: G1O[HOME][119] = 194; /* upper junction */
358: G1I[HOME][179] = 120;
359: G1O[HOME][120] = 179; /* vertival bar */
360: G1I[HOME][243] = 121;
361: G1O[HOME][121] = 243; /* lower equals */
362: G1I[HOME][242] = 122;
363: G1O[HOME][122] = 242; /* greater equals */
364: G1I[HOME][227] = 123;
365: G1O[HOME][123] = 227; /* pi */
366: G1I[HOME][246] = 124;
367: G1O[HOME][124] = 246; /* not equals */
368: G1I[HOME][128] = 125;
369: G1O[HOME][125] = 128; /* euro sign */
370: G1I[HOME][250] = 126;
371: G1O[HOME][126] = 250; /* centered dot */
372: #endif /* SCO */
373: }
374:
375: void init_signals (void)
376: {
377: sig_init ();
378: }
379:
380: void init_timezone (void)
381: {
382:
383: struct tm lt;
384: struct tm gt;
385:
386: unsigned long gmt;
387: unsigned long lmt;
388:
389: long clock;
390:
391: #ifdef __CYGWIN__
392:
393: tzset (); /* may be required in order */
394: /* to guarantee _timezone set */
395: #else
396:
397: clock = time (0L);
398: lt = *localtime (&clock);
399: gt = *gmtime (&clock);
400:
401: /* This is awkward but I think it is portable: steve_morris */
402: gmt = gt.tm_year * 365;
403: gmt = (gmt + gt.tm_yday) * 24;
404: gmt = (gmt + gt.tm_hour) * 60;
405: gmt = (gmt + gt.tm_min);
406:
407: lmt = lt.tm_year * 365;
408: lmt = (lmt + lt.tm_yday) * 24;
409: lmt = (lmt + lt.tm_hour) * 60;
410: lmt = (lmt + lt.tm_min);
411:
412: FreeM_timezone = (gmt - lmt) * 60;
413: tzoffset = -FreeM_timezone;
414:
415: #endif /* __CYGWIN__ */
416:
417:
418: }
419:
420: void init_freem_path (void)
421: {
422:
423: if((freem_path = malloc(PATH_MAX + 1)) == NULL) {
424: fprintf(stderr, "Can't allocate freem_path. Exiting.");
425:
426: exit(1);
427: }
428:
429: freem_path[0] = NUL;
430:
431: /* check where I'm being executed from */
432: #ifdef __linux__
433: readlink ("/proc/self/exe", freem_path, PATH_MAX);
434: #endif
435: #ifdef __FreeBSD__
436: readlink ("/proc/curproc/file", freem_path, PATH_MAX);
437: #endif
438: #ifdef __sun
439: readlink ("/proc/self/path/a.out", freem_path, PATH_MAX);
440: #endif
441:
442: if(freem_path[0] == NUL) {
443: /* we don't know where we came from */
444: }
445:
446: getcwd (curdir, PATHLEN);
447: stcnv_c2m (curdir);
448:
449: }
450:
451: #if defined(HAVE_LIBREADLINE)
452: void init_readline (void)
453: {
454: uid_t uid = geteuid ();
455: struct passwd *pw = getpwuid (uid);
456: char *pw_buf;
457:
458: pw_buf = (char *) calloc (strlen(pw->pw_dir) + 1, sizeof(char));
459: strcpy (pw_buf, pw->pw_dir);
460:
1.11 snw 461: snprintf (history_file, sizeof (history_file) - 1, "%s/.freem_history", pw_buf);
1.1 snw 462:
463: free (pw_buf);
464:
465: using_history ();
466: read_history (history_file);
467: }
468: #endif
469:
470: void init_execution_context (void)
471: {
472: register int i;
473:
474: obj_init ();
475:
476: merr_clear ();
477:
478: codptr = code;
479: code[0] = EOL; /* init code_pointer */
480: partition = calloc ((unsigned) (PSIZE + 2), 1);
481:
482: if (partition == NULL) exit (2); /* could not allocate stuff... */
483:
484: for (i = 0; i < MAXNO_OF_RBUF; i++) {
485: rbuf_flags[i].standard = standard;
486: }
487:
488: for (i = 0; i < NESTLEVLS; i++) {
489: extr_types[i] = DT_STRING;
490: }
491:
492: symlen = PSIZE;
493: s = &partition[PSIZE] - 256; /* pointer to symlen_offset */
494: argptr = partition; /* pointer to beg of tmp-storage */
495:
496: svntable = calloc ((unsigned) (UDFSVSIZ + 1), 1);
497: if (svntable == NULL) exit (2); /* could not allocate stuff... */
498:
499: svnlen = UDFSVSIZ; /* begin of udf_svn_table */
500: buff = calloc ((unsigned) NO_OF_RBUF * (unsigned) PSIZE0, 1); /* routine buffer pool */
501: if (buff == NULL) exit (2); /* could not allocate stuff... */
502:
503:
504: newstack = calloc ((unsigned) NSIZE, 1);
505: if (newstack == NULL) exit (2); /* could not allocate stuff... */
506:
507: #ifdef DEBUG_NEWPTR
508: printf("Allocating newptr stack...\r\n");
509: #endif
510:
511: newptr = newstack;
512: newlimit = newstack + NSIZE - 1024;
513:
514:
515: namstck = calloc ((unsigned) NESTLEVLS * 13, 1);
516: if (namstck == NULL) exit (2); /* could not allocate stuff... */
517:
518: *namstck = EOL;
519: *(namstck + 1) = EOL;
520: namptr = namstck; /* routine name stack pointer */
521: framstck = calloc ((unsigned) NESTLEVLS * 256, 1);
522: if (framstck == NULL) exit (2); /* could not allocate stuff... */
523:
524: *framstck = EOL;
525: *(framstck + 1) = EOL;
526: dofrmptr = framstck; /* DO_frame stack pointer */
527: cmdstack = calloc ((unsigned) NESTLEVLS * 256, 1);
528: if (cmdstack == NULL) exit (2); /* could not allocate stuff... */
529:
530: cmdptr = cmdstack; /* command stack */
531:
532: rouend = rouins = rouptr = buff;
533: roucur = buff + (NO_OF_RBUF * PSIZE0 + 1);
534: *rouptr = EOL;
535: *(rouptr + 1) = EOL;
536: *(rouptr + 2) = EOL;
537:
538: err_suppl[0] = EOL; /* empty out supplemental error info */
539: }
540:
541: void init_estack (void)
542: {
543: stcpy (merr_stack[0].PLACE, "xecline()\201");
544: }
545:
546: #if defined(HAVE_MWAPI_MOTIF)
547: void init_mwapi (void)
548: {
549: /*
550: if (getenv("DISPLAY") != NULL) {
551: gtk_init (0, NULL);
552: }
553: */
1.10 snw 554: /* TODO: init Motif/libXt */
1.1 snw 555: }
556: #else
557: void init_mwapi (void)
558: {
559: return;
560: }
561: #endif
562:
563: void init_io (void)
564: {
565: register int i;
566:
567: /* initialize screen */
568: setbuf (stdin, NULL); /* no input buffering */
569: glvnflag.all = 0L;
570: stcpy (buff, "\201");
571: writeHOME (buff);
572: sq_modes[0] = '+';
573: for (i = 0; i <= MAXDEV; ug_buf[i++][0] = EOL); /* init read-buffers */
574:
1.7 snw 575: frm_crlf[HOME] = frm_filter;
1.1 snw 576:
577: if (hardcopy) zbreakon = ENABLE; /* enable CTRL/B */
578:
579: set_io (MUMPS); /* set i/o parameters */
580:
1.8 snw 581: #if !defined(__AMIGA) && !defined(__OS2__)
1.1 snw 582: if (ttyname (HOME)) { /* for $IO of HOME */
583: strcpy (dev[HOME], ttyname (HOME));
584: dev[HOME][strlen (dev[HOME])] = EOL;
585: }
586: else {
587: dev[HOME][0] = EOL; /* ...we are in a pipe */
588: }
589: #else
1.8 snw 590: #if defined(__AMIGA)
1.1 snw 591: strcpy (dev[HOME], "CONSOLE:");
1.8 snw 592: #else
593: #if defined(__OS2__)
594: strcpy (dev[HOME], "CON:");
595: #endif
596: #endif
1.1 snw 597: #endif
598:
599: /* init function keys */
600: for (i = 0; i < 44; zfunkey[i++][0] = EOL);
601: }
602:
603: void init_random_number (void)
604: {
605:
606: srand (time (NULL));
607:
608: if ((nrandom = time (0L) * getpid ()) < 0) {
609: nrandom = (-nrandom);
610: }
611:
612: }
613:
614: void init_ztrap (void)
615: {
616:
617: if (frm_filter) {
618: ztrap[0][0] = EOL; /* no default ztrap for filters */
619: }
620: else if (startuprou[0] == '^') {
621: stcpy (ztrap[0], startuprou);
622: }
623: else {
624: stcpy (ztrap[0], "^%SYSINIT\201");
625: }
626:
627: /* $ZT to be xecuted on startup */
628:
629: stcpy (ztrap[NESTLEVLS + 1], ztrap[0]); /* DSM V.2 error trapping */
630:
631: }
632:
633: void init_ssvn(void)
634: {
635: ssvn_job_update ();
636: ssvn_display_update ();
637: ssvn_routine_update ();
638: ssvn_library_update ();
639: if (first_process) ssvn_system_update ();
640: }
641:
642: void init_terminal(void)
643: {
644: xpos[HOME] = 80;
645: ypos[HOME] = 24;
646: }
647:
648: void reset_terminal(void)
649: {
650: struct termio tpara;
651:
652: ioctl (0, TCGETA, &tpara);
653:
654: tpara.c_lflag |= (ECHO | ICANON); /* enable echo/no cbreak mode */
655: tpara.c_iflag |= ICRNL; /* cr-lf mapping */
656: tpara.c_oflag |= ONLCR; /* cr-lf mapping */
657: tpara.c_cc[VMIN] = EOT;
658: tpara.c_cc[VTIME] = -1;
659:
660: ioctl (0, TCSETA, &tpara);
661: }
662:
663: void cleanup (void)
664: {
665: char k_buf[256];
666: int ch;
667:
668: /* remove this job's entry from ^$JOB SSVN */
1.11 snw 669: snprintf (k_buf, sizeof (k_buf) - 1, "^$JOB\202%d\201", pid);
1.1 snw 670: symtab_shm (kill_sym, k_buf, " \201");
671:
672: reset_terminal ();
673:
674: if (tp_level > 0) {
675:
676: if (direct_mode == TRUE) {
677: fprintf (stderr, "UNCOMMITTED TRANSACTIONS EXIST:\n\n");
678: tp_tdump ();
679: set_io (UNIX);
680: fprintf (stderr, "\nWould you like to c)ommit or r)ollback the above transactions and their operations? ($TLEVEL = %d) ", tp_level);
681:
682: for (;;) {
683: ch = fgetc (stdin);
684:
685: if (ch == 'c' || ch == 'C') {
686: while (tp_level > 0) tp_tcommit ();
687:
688: fprintf (stderr, "\n\nTransactions have been committed.\n");
689:
690: break;
691: }
692: else if (ch == 'r' || ch == 'R') {
693: tp_trollback (tp_level);
694:
695: fprintf (stderr, "\n\nTransactions have been rolled back.\n");
696:
697: break;
698: }
699: else {
700: fprintf (stderr, "\n\nInvalid input '%c'. Must choose c)ommit or r)ollback.\n", ch);
701: }
702: }
703: }
704: else {
705: fprintf (stderr, "Uncommitted transactions exist. Rolling back.\n");
706: tp_trollback (tp_level);
707: }
708: }
709:
710: #if defined(HAVE_LIBREADLINE)
711: write_history (history_file);
712: #endif
713:
714: locktab_unlock_all ();
715: job_remove (pid);
716:
717: shm_exit ();
718:
719: if (run_daemon == TRUE) {
720:
721: if (pid_fd != -1) {
722: lockf (pid_fd, F_ULOCK, 0);
723: close (pid_fd);
724: }
725:
726: if (pid_file_path != NULL) {
727: unlink (pid_file_path);
728: }
729:
730: }
731:
732:
733:
734: free (buff); /* free previously allocated space */
735: free (svntable);
736: if (partition) free (partition);
737: if (apartition) free (apartition);
738:
739:
740: free (newstack);
741:
742:
743: if (v22size) free (v22ali);
744:
745: return;
746: } /* end of cleanup */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>