]> git.sur5r.net Git - openldap/blob - libraries/liblutil/utils.c
5024e907ffe2d584f4be959ea7bb1b0068d2da3f
[openldap] / libraries / liblutil / utils.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6
7 #include "portable.h"
8
9 #include <ac/stdlib.h>
10 #include <ac/string.h>
11 #include <ac/unistd.h>
12 #ifdef HAVE_IO_H
13 #include <io.h>
14 #endif
15 #ifdef HAVE_FCNTL_H
16 #include <fcntl.h>
17 #endif
18
19 #include <lber.h>
20 #include <lutil.h>
21 #include <ldap_defaults.h>
22
23 char* lutil_progname( const char* name, int argc, char *argv[] )
24 {
25         char *progname;
26
27         if(argc == 0) {
28                 return ber_strdup( name );
29         }
30
31         progname = strrchr ( argv[0], *LDAP_DIRSEP );
32         progname = ber_strdup( progname ? &progname[1] : argv[0] );
33
34         return progname;
35 }
36
37 #ifndef HAVE_MKSTEMP
38 int mkstemp( char * template )
39 {
40 #ifdef HAVE_MKTEMP
41         return open ( mktemp ( template ), O_RDWR|O_CREAT|O_EXCL, 0600 );
42 #else
43         return -1;
44 #endif
45 }
46 #endif
47
48 #ifndef HAVE_VSNPRINTF
49 #include <ac/stdarg.h>
50 #include <ac/signal.h>
51 #include <stdio.h>
52
53 /* Write at most n characters to the buffer in str, return the
54  * number of chars written or -1 if the buffer would have been
55  * overflowed.
56  *
57  * This is portable to any POSIX-compliant system. We use pipe()
58  * to create a valid file descriptor, and then fdopen() it to get
59  * a valid FILE pointer. The user's buffer and size are assigned
60  * to the FILE pointer using setvbuf. Then we close the read side
61  * of the pipe to invalidate the descriptor.
62  *
63  * If the write arguments all fit into size n, the write will
64  * return successfully. If the write is too large, the stdio
65  * buffer will need to be flushed to the underlying file descriptor.
66  * The flush will fail because it is attempting to write to a
67  * broken pipe, and the write will be terminated.
68  *
69  * Note: glibc's setvbuf is broken, so this code fails on glibc.
70  * But that's no loss since glibc provides these functions itself.
71  *
72  * In practice, the main app will probably have ignored SIGPIPE
73  * already, so catching it here is redundant, but harmless.
74  *
75  * -- hyc, 2002-07-19
76  */
77 int vsnprintf( char *str, size_t n, const char *fmt, va_list ap )
78 {
79         int fds[2], res;
80         FILE *f;
81 #ifdef SIGPIPE
82         RETSIGTYPE (*sig)();
83 #endif
84
85         if (pipe( fds )) return -1;
86
87         f = fdopen( fds[1], "w" );
88         if ( !f ) {
89                 close( fds[1] );
90                 close( fds[0] );
91                 return -1;
92         }
93 #ifdef SIGPIPE
94         sig = SIGNAL( SIGPIPE, SIG_IGN );
95 #endif
96         setvbuf( f, str, _IOFBF, n );
97         close( fds[0] );
98
99         res = vfprintf( f, fmt, ap );
100         fclose( f );
101 #ifdef SIGPIPE
102         SIGNAL( SIGPIPE, sig );
103 #endif
104         return res;
105 }
106
107 int snprintf( char *str, size_t n, const char *fmt, ... )
108 {
109         va_list ap;
110         int res;
111
112         va_start( ap, fmt );
113         res = vsnprintf( str, n, fmt, ap );
114         va_end( ap );
115         return res;
116 }
117 #endif /* !HAVE_VSNPRINTF */