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