1 /* $NetBSD: util.c,v 1.47 2008/12/13 15:19:29 dsl Exp $ */
4 * Missing stuff from OS's
8 static char rcsid
[] = "$NetBSD: util.c,v 1.47 2008/12/13 15:19:29 dsl Exp $";
10 #include <sys/cdefs.h>
12 __RCSID("$NetBSD: util.c,v 1.47 2008/12/13 15:19:29 dsl Exp $");
16 #include <sys/param.h>
24 #if !defined(MAKE_NATIVE) && !defined(HAVE_STRERROR)
25 extern int errno
, sys_nerr
;
26 extern char *sys_errlist
[];
32 if (e
< 0 || e
>= sys_nerr
) {
33 snprintf(buf
, sizeof(buf
), "Unknown error %d", e
);
37 return sys_errlist
[e
];
41 #if !defined(MAKE_NATIVE) && !defined(HAVE_SETENV)
42 extern char **environ
;
45 findenv(const char *name
, int *offset
)
50 for (i
= 0; (q
= environ
[i
]); i
++) {
51 char *p
= strchr(q
, '=');
54 if (strncmp(name
, q
, len
= p
- q
) == 0) {
64 unsetenv(const char *name
)
69 if (name
== NULL
|| *name
== '\0' || strchr(name
, '=') != NULL
) {
74 while (findenv(name
, &offset
)) { /* if set multiple times */
75 for (p
= &environ
[offset
];; ++p
)
83 setenv(const char *name
, const char *value
, int rewrite
)
85 static char **saveenv
; /* copy of previously allocated space */
91 if (name
== NULL
|| value
== NULL
) {
96 if (*value
== '=') /* no `=' in value */
98 l_value
= strlen(value
);
100 /* find if already exists */
101 if ((c
= findenv(name
, &offset
))) {
104 if (strlen(c
) >= l_value
) /* old larger; copy over */
106 } else { /* create new slot */
107 size
= sizeof(char *) * (offset
+ 2);
108 if (saveenv
== environ
) { /* just increase size */
109 if ((newenv
= realloc(saveenv
, size
)) == NULL
)
112 } else { /* get new space */
114 * We don't free here because we don't know if
115 * the first allocation is valid on all OS's
117 if ((saveenv
= malloc(size
)) == NULL
)
119 (void)memcpy(saveenv
, environ
, size
- sizeof(char *));
122 environ
[offset
+ 1] = NULL
;
124 for (cc
= name
; *cc
&& *cc
!= '='; ++cc
) /* no `=' in name */
127 /* name + `=' + value */
128 if ((environ
[offset
] = malloc(size
+ l_value
+ 2)) == NULL
)
131 (void)memcpy(c
, name
, size
);
135 (void)memcpy(c
, value
, l_value
+ 1);
141 main(int argc
, char *argv
[])
143 setenv(argv
[1], argv
[2], 0);
144 printf("%s\n", getenv(argv
[1]));
146 printf("%s\n", getenv(argv
[1]));
153 #if defined(__hpux__) || defined(__hpux)
155 * Like strcpy, going backwards and returning the new pointer
158 strrcpy(char *ptr
, char *str
)
160 int len
= strlen(str
);
168 char *sys_siglist
[] = {
170 "Hangup", /* SIGHUP */
171 "Interrupt", /* SIGINT */
172 "Quit", /* SIGQUIT */
173 "Illegal instruction", /* SIGILL */
174 "Trace/BPT trap", /* SIGTRAP */
175 "IOT trap", /* SIGIOT */
176 "EMT trap", /* SIGEMT */
177 "Floating point exception", /* SIGFPE */
178 "Killed", /* SIGKILL */
179 "Bus error", /* SIGBUS */
180 "Segmentation fault", /* SIGSEGV */
181 "Bad system call", /* SIGSYS */
182 "Broken pipe", /* SIGPIPE */
183 "Alarm clock", /* SIGALRM */
184 "Terminated", /* SIGTERM */
185 "User defined signal 1", /* SIGUSR1 */
186 "User defined signal 2", /* SIGUSR2 */
187 "Child exited", /* SIGCLD */
188 "Power-fail restart", /* SIGPWR */
189 "Virtual timer expired", /* SIGVTALRM */
190 "Profiling timer expired", /* SIGPROF */
191 "I/O possible", /* SIGIO */
192 "Window size changes", /* SIGWINDOW */
193 "Stopped (signal)", /* SIGSTOP */
194 "Stopped", /* SIGTSTP */
195 "Continued", /* SIGCONT */
196 "Stopped (tty input)", /* SIGTTIN */
197 "Stopped (tty output)", /* SIGTTOU */
198 "Urgent I/O condition", /* SIGURG */
199 "Remote lock lost (NFS)", /* SIGLOST */
200 "Signal 31", /* reserved */
201 "DIL signal" /* SIGDIL */
203 #endif /* __hpux__ || __hpux */
205 #if defined(__hpux__) || defined(__hpux)
206 #include <sys/types.h>
207 #include <sys/syscall.h>
208 #include <sys/signal.h>
209 #include <sys/stat.h>
211 #include <sys/time.h>
215 killpg(int pid
, int sig
)
217 return kill(-pid
, sig
);
220 #if !defined(__hpux__) && !defined(__hpux)
234 /* turn into bsd signals */
236 signal(int s
, void (*a
)(int)))(int)
238 struct sigvec osv
, sv
;
240 (void)sigvector(s
, NULL
, &osv
);
244 sv
.sv_flags
= SV_BSDSIG
;
247 if (sigvector(s
, &sv
, NULL
) == -1)
249 return (osv
.sv_handler
);
252 #if !defined(__hpux__) && !defined(__hpux)
254 utimes(char *file
, struct timeval tvp
[2])
258 t
.actime
= tvp
[0].tv_sec
;
259 t
.modtime
= tvp
[1].tv_sec
;
260 return(utime(file
, &t
));
264 #if !defined(BSD) && !defined(d_fileno)
265 # define d_fileno d_ino
268 #ifndef DEV_DEV_COMPARE
269 # define DEV_DEV_COMPARE(a, b) ((a) == (b))
271 #define ISDOT(c) ((c)[0] == '.' && (((c)[1] == '\0') || ((c)[1] == '/')))
272 #define ISDOTDOT(c) ((c)[0] == '.' && ISDOT(&((c)[1])))
275 getwd(char *pathname
)
281 struct stat st_root
, st_cur
, st_next
, st_dotdot
;
282 char pathbuf
[MAXPATHLEN
], nextpathbuf
[MAXPATHLEN
* 2];
283 char *pathptr
, *nextpathptr
, *cur_name_add
;
285 /* find the inode of root */
286 if (stat("/", &st_root
) == -1) {
287 (void)sprintf(pathname
,
288 "getwd: Cannot stat \"/\" (%s)", strerror(errno
));
291 pathbuf
[MAXPATHLEN
- 1] = '\0';
292 pathptr
= &pathbuf
[MAXPATHLEN
- 1];
293 nextpathbuf
[MAXPATHLEN
- 1] = '\0';
294 cur_name_add
= nextpathptr
= &nextpathbuf
[MAXPATHLEN
- 1];
296 /* find the inode of the current directory */
297 if (lstat(".", &st_cur
) == -1) {
298 (void)sprintf(pathname
,
299 "getwd: Cannot stat \".\" (%s)", strerror(errno
));
302 nextpathptr
= strrcpy(nextpathptr
, "../");
304 /* Descend to root */
307 /* look if we found root yet */
308 if (st_cur
.st_ino
== st_root
.st_ino
&&
309 DEV_DEV_COMPARE(st_cur
.st_dev
, st_root
.st_dev
)) {
310 (void)strcpy(pathname
, *pathptr
!= '/' ? "/" : pathptr
);
314 /* open the parent directory */
315 if (stat(nextpathptr
, &st_dotdot
) == -1) {
316 (void)sprintf(pathname
,
317 "getwd: Cannot stat directory \"%s\" (%s)",
318 nextpathptr
, strerror(errno
));
321 if ((dp
= opendir(nextpathptr
)) == NULL
) {
322 (void)sprintf(pathname
,
323 "getwd: Cannot open directory \"%s\" (%s)",
324 nextpathptr
, strerror(errno
));
328 /* look in the parent for the entry with the same inode */
329 if (DEV_DEV_COMPARE(st_dotdot
.st_dev
, st_cur
.st_dev
)) {
330 /* Parent has same device. No need to stat every member */
331 for (d
= readdir(dp
); d
!= NULL
; d
= readdir(dp
))
332 if (d
->d_fileno
== st_cur
.st_ino
)
337 * Parent has a different device. This is a mount point so we
338 * need to stat every member
340 for (d
= readdir(dp
); d
!= NULL
; d
= readdir(dp
)) {
341 if (ISDOT(d
->d_name
) || ISDOTDOT(d
->d_name
))
343 (void)strcpy(cur_name_add
, d
->d_name
);
344 if (lstat(nextpathptr
, &st_next
) == -1) {
345 (void)sprintf(pathname
,
346 "getwd: Cannot stat \"%s\" (%s)",
347 d
->d_name
, strerror(errno
));
351 /* check if we found it yet */
352 if (st_next
.st_ino
== st_cur
.st_ino
&&
353 DEV_DEV_COMPARE(st_next
.st_dev
, st_cur
.st_dev
))
358 (void)sprintf(pathname
,
359 "getwd: Cannot find \".\" in \"..\"");
364 pathptr
= strrcpy(pathptr
, d
->d_name
);
365 pathptr
= strrcpy(pathptr
, "/");
366 nextpathptr
= strrcpy(nextpathptr
, "../");
368 *cur_name_add
= '\0';
373 #if defined(sun) && defined(__svr4__)
376 /* turn into bsd signals */
378 signal(int s
, void (*a
)(int)))(int)
380 struct sigaction sa
, osa
;
383 sigemptyset(&sa
.sa_mask
);
384 sa
.sa_flags
= SA_RESTART
;
386 if (sigaction(s
, &sa
, &osa
) == -1)
389 return osa
.sa_handler
;
393 #if !defined(MAKE_NATIVE) && !defined(HAVE_VSNPRINTF)
396 #if !defined(__osf__)
398 #define STRFLAG (_IOSTRG|_IOWRT) /* no _IOWRT: avoid stdio bug */
401 #define STRFLAG (_IOREAD) /* XXX: Assume svr4 stdio */
407 vsnprintf(char *s
, size_t n
, const char *fmt
, va_list args
)
412 fakebuf
._flag
= STRFLAG
;
414 * Some os's are char * _ptr, others are unsigned char *_ptr...
415 * We cast to void * to make everyone happy.
417 fakebuf
._ptr
= (void *)s
;
420 _doprnt(fmt
, args
, &fakebuf
);
422 putc('\0', &fakebuf
);
425 return (n
-fakebuf
._cnt
-1);
427 (void)vsprintf(s
, fmt
, args
);
433 snprintf(char *s
, size_t n
, const char *fmt
, ...)
439 rv
= vsnprintf(s
, n
, fmt
, ap
);
444 #if !defined(MAKE_NATIVE) && !defined(HAVE_STRFTIME)
446 strftime(char *buf
, size_t len
, const char *fmt
, const struct tm
*tm
)
448 static char months
[][4] = {
449 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
450 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
468 if (len
== 0) return buf
- b
;
475 s
= snprintf(buf
, len
, "%d", tm
->tm_hour
);
478 s
= snprintf(buf
, len
, "%02d", tm
->tm_min
);
481 s
= snprintf(buf
, len
, "%02d", tm
->tm_sec
);
484 if (tm
->tm_mon
>= 12)
486 s
= snprintf(buf
, len
, "%s", months
[tm
->tm_mon
]);
489 s
= snprintf(buf
, len
, "%02d", tm
->tm_mday
);
492 s
= snprintf(buf
, len
, "%d", 1900 + tm
->tm_year
);
495 s
= snprintf(buf
, len
, "Unsupported format %c",