Home | History | Annotate | Download | only in testsuite
      1 /*
      2  * Copyright (C) 2012-2013  ProFUSION embedded systems
      3  *
      4  * This program is free software; you can redistribute it and/or
      5  * modify it under the terms of the GNU Lesser General Public
      6  * License as published by the Free Software Foundation; either
      7  * version 2.1 of the License, or (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     12  * Lesser General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU Lesser General Public
     15  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     16  */
     17 
     18 #include <dlfcn.h>
     19 #include <errno.h>
     20 #include <stdio.h>
     21 #include <stdlib.h>
     22 #include <string.h>
     23 #include <unistd.h>
     24 #include <sys/utsname.h>
     25 
     26 #include "testsuite.h"
     27 
     28 TS_EXPORT int uname(struct utsname *u)
     29 {
     30 	static void *nextlib = NULL;
     31 	static int (*nextlib_uname)(struct utsname *u);
     32 	const char *release;
     33 	int err;
     34 	size_t sz;
     35 
     36 	if (nextlib == NULL) {
     37 #ifdef RTLD_NEXT
     38 		nextlib = RTLD_NEXT;
     39 #else
     40 		nextlib = dlopen("libc.so.6", RTLD_LAZY);
     41 #endif
     42 		nextlib_uname = dlsym(nextlib, "uname");
     43 	}
     44 
     45 	err = nextlib_uname(u);
     46 	if (err < 0)
     47 		return err;
     48 
     49 	if (!environ)
     50 		/*
     51 		 * probably called from within glibc before main(); unsafe
     52 		 * to call getenv()
     53 		 */
     54 		return 0;
     55 
     56 	release = getenv(S_TC_UNAME_R);
     57 	if (release == NULL) {
     58 		fprintf(stderr, "TRAP uname(): missing export %s?\n",
     59 							S_TC_UNAME_R);
     60 		return 0;
     61 	}
     62 
     63 	sz = strlen(release) + 1;
     64 	if (sz > sizeof(u->release)) {
     65 		fprintf(stderr, "uname(): sizeof release (%s) "
     66 				"is greater than available space: %zu",
     67 				release, sizeof(u->release));
     68 		errno = -EFAULT;
     69 		return -1;
     70 	}
     71 
     72 	memcpy(u->release, release, sz);
     73 	return 0;
     74 }
     75