# # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2015, Richard Lowe. include $(SRC)/Makefile.master SUBDIRS = $(MACH64) all : TARGET = all install : TARGET = install clean : TARGET = clean clobber : TARGET = clobber .KEEP_STATE: all clean clobber install: $(SUBDIRS) _msg: $(SUBDIRS): FRC @cd $@; pwd; $(MAKE) $(TARGET) FRC: # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2015, Richard Lowe. LIBRARY = libmakestate.a VERS = .1 OBJECTS = ld_file.o \ lock.o include $(SRC)/lib/Makefile.lib include ../../../Makefile.com LIBS = $(DYNLIB) SRCDIR = ../ MAPFILES = $(SRCDIR)/mapfile-vers LDLIBS += -lc all: $(LIBS) include $(SRC)/lib/Makefile.targ # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2015, Richard Lowe. include ../Makefile.com include $(SRC)/lib/Makefile.lib.64 install: all $(ROOTLIBS64) /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 1998 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma init(ld_support_init) #include #include #include #include #include #include #include #define SUNPRO_DEPENDENCIES "SUNPRO_DEPENDENCIES" /* * Linked list of strings - used to keep lists of names * of directories or files. */ struct Stritem { char *str; void *next; }; typedef struct Stritem Stritem; static char *depend_file = NULL; static Stritem *list = NULL; void mk_state_init(void) { depend_file = getenv(SUNPRO_DEPENDENCIES); } /* mk_state_init() */ static void prepend_str(Stritem **list, const char *str) { Stritem *new; char *newstr; if (!(new = calloc(1, sizeof (Stritem)))) { perror("libmakestate.so"); return; } /* if */ if (!(newstr = malloc(strlen(str) + 1))) { perror("libmakestate.so"); return; } /* if */ new->str = strcpy(newstr, str); new->next = *list; *list = new; } /* prepend_str() */ void mk_state_collect_dep(const char *file) { /* * SUNPRO_DEPENDENCIES wasn't set, we don't collect .make.state * information. */ if (!depend_file) return; prepend_str(&list, file); } /* mk_state_collect_dep() */ void mk_state_update_exit() { Stritem *cur; char lockfile[MAXPATHLEN], *err, *space, *target; FILE *ofp; extern char *file_lock(char *, char *, int); if (!depend_file) return; if ((space = strchr(depend_file, ' ')) == NULL) return; *space = '\0'; target = &space[1]; (void) sprintf(lockfile, "%s.lock", depend_file); if ((err = file_lock(depend_file, lockfile, 0))) { (void) fprintf(stderr, "%s\n", err); return; } /* if */ if (!(ofp = fopen(depend_file, "a"))) return; if (list) (void) fprintf(ofp, "%s: ", target); for (cur = list; cur; cur = cur->next) (void) fprintf(ofp, " %s", cur->str); (void) fputc('\n', ofp); (void) fclose(ofp); (void) unlink(lockfile); *space = ' '; } /* mk_state_update_exit() */ static void ld_support_init() { mk_state_init(); } /* ld_support_init() */ void ld_file(const char *file, const Elf_Kind ekind, int flags, Elf *elf) { if (!((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED))) return; mk_state_collect_dep(file); } /* ld_file */ void ld_atexit(int exit_code) { if (exit_code) return; mk_state_update_exit(); } /* ld_atexit() */ /* * Supporting 64-bit objects */ void ld_file64(const char *file, const Elf_Kind ekind, int flags, Elf *elf) { if (!((flags & LD_SUP_DERIVED) && !(flags & LD_SUP_EXTRACTED))) return; mk_state_collect_dep(file); } /* ld_file64 */ void ld_atexit64(int exit_code) { if (exit_code) return; mk_state_update_exit(); } /* ld_atexit64() */ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include #include #include #include #include /* errno */ #if defined(_LP64) /* * The symbols _sys_errlist and _sys_nerr are not visible in the * LP64 libc. Use strerror(3C) instead. */ #else /* #_LP64 */ extern char * sys_errlist[]; extern int sys_nerr; #endif /* #_LP64 */ static void file_lock_error(); /* * This code stolen from the NSE library and changed to not depend * upon any NSE routines or header files. * * Simple file locking. * Create a symlink to a file. The "test and set" will be * atomic as creating the symlink provides both functions. * * The timeout value specifies how long to wait for stale locks * to disappear. If the lock is more than 'timeout' seconds old * then it is ok to blow it away. This part has a small window * of vunerability as the operations of testing the time, * removing the lock and creating a new one are not atomic. * It would be possible for two processes to both decide to blow * away the lock and then have process A remove the lock and establish * its own, and then then have process B remove the lock which accidentily * removes A's lock rather than the stale one. * * A further complication is with the NFS. If the file in question is * being served by an NFS server, then its time is set by that server. * We can not use the time on the client machine to check for a stale * lock. Therefore, a temp file on the server is created to get * the servers current time. * * Returns an error message. NULL return means the lock was obtained. * */ char * file_lock(char * name, char * lockname, int timeout) { int r; int fd; struct stat statb; struct stat fs_statb; char tmpname[MAXPATHLEN]; static char msg[MAXPATHLEN]; if (timeout <= 0) { timeout = 15; } for (;;) { r = symlink(name, lockname); if (r == 0) { return (NULL); } if (errno != EEXIST) { file_lock_error(msg, name, (const char *)"symlink(%s, %s)", name, lockname); return (msg); } for (;;) { (void) sleep(1); r = lstat(lockname, &statb); if (r == -1) { /* * The lock must have just gone away - try * again. */ break; } /* * With the NFS the time given a file is the time on * the file server. This time may vary from the * client's time. Therefore, we create a tmpfile in * the same directory to establish the time on the * server and use this time to see if the lock has * expired. */ (void) sprintf(tmpname, "%s.XXXXXX", lockname); (void) mktemp(tmpname); fd = creat(tmpname, 0666); if (fd != -1) { (void) close(fd); } else { file_lock_error(msg, name, (const char *)"creat(%s)", tmpname); return (msg); } if (stat(tmpname, &fs_statb) == -1) { file_lock_error(msg, name, (const char *)"stat(%s)", tmpname); return (msg); } (void) unlink(tmpname); if (statb.st_mtime + timeout < fs_statb.st_mtime) { /* * The lock has expired - blow it away. */ (void) unlink(lockname); break; } } } /* NOTREACHED */ } /* * Format a message telling why the lock could not be created. */ /* VARARGS4 */ static void file_lock_error(char * msg, char * file, const char * str, char * arg1, char * arg2) { int len; (void) sprintf(msg, "Could not lock file `%s'; ", file); len = strlen(msg); (void) sprintf(&msg[len], str, arg1, arg2); (void) strcat(msg, " failed - "); #if defined(_LP64) /* Needs to be changed to use strerror(3C) instead. */ len = strlen(msg); (void) sprintf(&msg[len], "errno %d", errno); #else /* #_LP64 */ if (errno < sys_nerr) { (void) strcat(msg, sys_errlist[errno]); } else { len = strlen(msg); (void) sprintf(&msg[len], "errno %d", errno); } #endif /* #_LP64 */ } # # This file and its contents are supplied under the terms of the # Common Development and Distribution License ("CDDL"), version 1.0. # You may only use this file in accordance with the terms of version # 1.0 of the CDDL. # # A full copy of the text of the CDDL should have accompanied this # source. A copy of the CDDL is also available via the Internet at # http://www.illumos.org/license/CDDL. # # Copyright 2015, Richard Lowe. # # MAPFILE HEADER START # # WARNING: STOP NOW. DO NOT MODIFY THIS FILE. # Object versioning must comply with the rules detailed in # # usr/src/lib/README.mapfiles # # You should not be making modifications here until you've read the most current # copy of that file. If you need help, contact a gatekeeper for guidance. # # MAPFILE HEADER END # $mapfile_version 2 SYMBOL_VERSION ILLUMOSprivate { global: ld_atexit; ld_atexit64; ld_file; ld_file64; local: *; };