annotate dpid/misc_new.c @ 0:6ee11bf9e3ea

Initial revision
author jcid
date Sun, 07 Oct 2007 00:36:34 +0200
parents
children f1eca1aba94a
rev   line source
0
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
1 #include <stdio.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
2 #include <time.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
3 #include <stdlib.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
4 #include <string.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
5 #include <unistd.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
6 #include <sys/stat.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
7 #include <sys/types.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
8 #include <errno.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
9 #include <fcntl.h>
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
10 #include "d_size.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
11 #include "misc_new.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
12 #include "dpid_common.h"
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
13
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
14 #include "misc_new.h" /* for function prototypes */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
15
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
16
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
17 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
18 * Close a FD handling EINTR.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
19 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
20 int a_Misc_close_fd(int fd)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
21 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
22 int st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
23
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
24 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
25 st = close(fd);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
26 } while (st < 0 && errno == EINTR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
27 return st;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
28 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
29
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
30 /*! Reads a dpi tag from a socket
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
31 * \li Continues after a signal interrupt
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
32 * \Return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
33 * Dstr pointer to tag on success, NULL on failure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
34 * \important Caller is responsible for freeing the returned Dstr *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
35 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
36 Dstr *a_Misc_rdtag(int socket)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
37 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
38 char c = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
39 ssize_t rdlen;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
40 Dstr *tag;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
41
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
42 tag = dStr_sized_new(64);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
43
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
44 errno = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
45
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
46 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
47 rdlen = read(socket, &c, 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
48 if (rdlen == -1 && errno != EINTR)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
49 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
50 dStr_append_c(tag, c);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
51 } while (c != '>');
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
52
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
53 if (rdlen == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
54 perror("a_Misc_rdtag");
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
55 dStr_free(tag, TRUE);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
56 return (NULL);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
57 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
58 return (tag);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
59 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
60
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
61 /*!
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
62 * Read a dpi tag from sock
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
63 * \return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
64 * pointer to dynamically allocated request tag
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
65 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
66 char *a_Misc_readtag(int sock)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
67 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
68 char *tag, c, buf[10];
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
69 size_t buflen, i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
70 size_t taglen = 0, tagmem = 10;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
71 ssize_t rdln = 1;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
72
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
73 tag = NULL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
74 buf[0] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
75 buflen = sizeof(buf) / sizeof(buf[0]);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
76 // new start
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
77 tag = (char *) dMalloc(tagmem + 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
78 for (i = 0; (rdln = read(sock, &c, 1)) != 0; i++) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
79 if (i == tagmem) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
80 tagmem += tagmem;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
81 tag = (char *) dRealloc(tag, tagmem + 1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
82 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
83 tag[i] = c;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
84 taglen += rdln;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
85 if (c == '>') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
86 tag[i + 1] = '\0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
87 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
88 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
89 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
90 // new end
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
91 if (rdln == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
92 ERRMSG("a_Misc_readtag", "read", errno);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
93 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
94
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
95 return (tag);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
96 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
97
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
98 /*! Reads a dpi tag from a socket without hanging on read.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
99 * \li Continues after a signal interrupt
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
100 * \Return
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
101 * \li 1 on success
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
102 * \li 0 if input is not available within timeout microseconds.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
103 * \li -1 on failure
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
104 * \important Caller is responsible for freeing the returned Dstr *
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
105 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
106 /* Is this useful?
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
107 int a_Misc_nohang_rdtag(int socket, int timeout, Dstr **tag)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
108 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
109 int n_fd;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
110 fd_set sock_set, select_set;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
111 struct timeval tout;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
112
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
113 FD_ZERO(&sock_set);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
114 FD_SET(socket, &sock_set);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
115
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
116 errno = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
117 do {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
118 select_set = sock_set;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
119 tout.tv_sec = 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
120 tout.tv_usec = timeout;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
121 n_fd = select(socket + 1, &select_set, NULL, NULL, &tout);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
122 } while (n_fd == -1 && errno == EINTR);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
123
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
124 if (n_fd == -1) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
125 MSG_ERR("%s:%d: a_Misc_nohang_rdtag: %s\n",
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
126 __FILE__, __LINE__, dStrerror(errno));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
127 return(-1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
128 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
129 if (n_fd == 0) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
130 return(0);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
131 } else {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
132 *tag = a_Misc_rdtag(socket);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
133 return(1);
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
134 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
135 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
136 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
137
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
138 /*
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
139 * Alternative to mkdtemp().
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
140 * Not as strong as mkdtemp, but enough for creating a directory.
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
141 * (adapted from dietlibc)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
142 */
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
143 char *a_Misc_mkdtemp(char *template)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
144 {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
145 char *tmp = template + strlen(template) - 6;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
146 int i;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
147 unsigned int random;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
148
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
149 if (tmp < template)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
150 goto error;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
151 for (i = 0; i < 6; ++i)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
152 if (tmp[i] != 'X') {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
153 error:
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
154 errno = EINVAL;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
155 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
156 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
157 srand((uint_t)(time(0) ^ getpid()));
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
158 for (;;) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
159 random = (unsigned) rand();
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
160 for (i = 0; i < 6; ++i) {
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
161 int hexdigit = (random >> (i * 5)) & 0x1f;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
162
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
163 tmp[i] = hexdigit > 9 ? hexdigit + 'a' - 10 : hexdigit + '0';
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
164 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
165 if (mkdir(template, 0700) == 0)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
166 break;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
167 if (errno == EEXIST)
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
168 continue;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
169 return 0;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
170 }
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
171 return template;
6ee11bf9e3ea Initial revision
jcid
parents:
diff changeset
172 }