tool_main.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
9  *
10  * This software is licensed as described in the file COPYING, which
11  * you should have received as part of this distribution. The terms
12  * are also available at https://curl.haxx.se/docs/copyright.html.
13  *
14  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15  * copies of the Software, and permit persons to whom the Software is
16  * furnished to do so, under the terms of the COPYING file.
17  *
18  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19  * KIND, either express or implied.
20  *
21  ***************************************************************************/
22 #include "tool_setup.h"
23 
24 #include <sys/stat.h>
25 
26 #ifdef HAVE_SIGNAL_H
27 #include <signal.h>
28 #endif
29 
30 #ifdef USE_NSS
31 #include <nspr.h>
32 #include <plarenas.h>
33 #endif
34 
35 #define ENABLE_CURLX_PRINTF
36 /* use our own printf() functions */
37 #include "curlx.h"
38 
39 #include "tool_cfgable.h"
40 #include "tool_convert.h"
41 #include "tool_msgs.h"
42 #include "tool_operate.h"
43 #include "tool_panykey.h"
44 #include "tool_vms.h"
45 #include "tool_main.h"
46 #include "tool_libinfo.h"
47 
48 /*
49  * This is low-level hard-hacking memory leak tracking and similar. Using
50  * the library level code from this client-side is ugly, but we do this
51  * anyway for convenience.
52  */
53 #include "memdebug.h" /* keep this as LAST include */
54 
55 #ifdef __VMS
56 /*
57  * vms_show is a global variable, used in main() as parameter for
58  * function vms_special_exit() to allow proper curl tool exiting.
59  * Its value may be set in other tool_*.c source files thanks to
60  * forward declaration present in tool_vms.h
61  */
62 int vms_show = 0;
63 #endif
64 
65 #ifdef __MINGW32__
66 /*
67  * There seems to be no way to escape "*" in command-line arguments with MinGW
68  * when command-line argument globbing is enabled under the MSYS shell, so turn
69  * it off.
70  */
71 int _CRT_glob = 0;
72 #endif /* __MINGW32__ */
73 
74 /* if we build a static library for unit tests, there is no main() function */
75 #ifndef UNITTESTS
76 
77 /*
78  * Ensure that file descriptors 0, 1 and 2 (stdin, stdout, stderr) are
79  * open before starting to run. Otherwise, the first three network
80  * sockets opened by curl could be used for input sources, downloaded data
81  * or error logs as they will effectively be stdin, stdout and/or stderr.
82  */
83 static void main_checkfds(void)
84 {
85 #ifdef HAVE_PIPE
86  int fd[2] = { STDIN_FILENO, STDIN_FILENO };
87  while(fd[0] == STDIN_FILENO ||
88  fd[0] == STDOUT_FILENO ||
89  fd[0] == STDERR_FILENO ||
90  fd[1] == STDIN_FILENO ||
91  fd[1] == STDOUT_FILENO ||
92  fd[1] == STDERR_FILENO)
93  if(pipe(fd) < 0)
94  return; /* Out of handles. This isn't really a big problem now, but
95  will be when we try to create a socket later. */
96  close(fd[0]);
97  close(fd[1]);
98 #endif
99 }
100 
101 #ifdef CURLDEBUG
102 static void memory_tracking_init(void)
103 {
104  char *env;
105  /* if CURL_MEMDEBUG is set, this starts memory tracking message logging */
106  env = curlx_getenv("CURL_MEMDEBUG");
107  if(env) {
108  /* use the value as file name */
109  char fname[CURL_MT_LOGFNAME_BUFSIZE];
110  if(strlen(env) >= CURL_MT_LOGFNAME_BUFSIZE)
111  env[CURL_MT_LOGFNAME_BUFSIZE-1] = '\0';
112  strcpy(fname, env);
113  curl_free(env);
114  curl_memdebug(fname);
115  /* this weird stuff here is to make curl_free() get called
116  before curl_memdebug() as otherwise memory tracking will
117  log a free() without an alloc! */
118  }
119  /* if CURL_MEMLIMIT is set, this enables fail-on-alloc-number-N feature */
120  env = curlx_getenv("CURL_MEMLIMIT");
121  if(env) {
122  char *endptr;
123  long num = strtol(env, &endptr, 10);
124  if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
125  curl_memlimit(num);
126  curl_free(env);
127  }
128 }
129 #else
130 # define memory_tracking_init() Curl_nop_stmt
131 #endif
132 
133 /*
134  * This is the main global constructor for the app. Call this before
135  * _any_ libcurl usage. If this fails, *NO* libcurl functions may be
136  * used, or havoc may be the result.
137  */
139 {
141 
142 #if defined(__DJGPP__) || defined(__GO32__)
143  /* stop stat() wasting time */
144  _djstat_flags |= _STAT_INODE | _STAT_EXEC_MAGIC | _STAT_DIRSIZE;
145 #endif
146 
147  /* Initialise the global config */
148  config->showerror = -1; /* Will show errors */
149  config->errors = stderr; /* Default errors to stderr */
150 
151  /* Allocate the initial operate config */
152  config->first = config->last = malloc(sizeof(struct OperationConfig));
153  if(config->first) {
154  /* Perform the libcurl initialization */
156  if(!result) {
157  /* Get information about libcurl */
158  result = get_libcurl_info();
159 
160  if(!result) {
161  /* Get a curl handle to use for all forthcoming curl transfers */
162  config->easy = curl_easy_init();
163  if(config->easy) {
164  /* Initialise the config */
165  config_init(config->first);
166  config->first->easy = config->easy;
167  config->first->global = config;
168  }
169  else {
170  helpf(stderr, "error initializing curl easy handle\n");
171  result = CURLE_FAILED_INIT;
172  free(config->first);
173  }
174  }
175  else {
176  helpf(stderr, "error retrieving curl library information\n");
177  free(config->first);
178  }
179  }
180  else {
181  helpf(stderr, "error initializing curl library\n");
182  free(config->first);
183  }
184  }
185  else {
186  helpf(stderr, "error initializing curl\n");
187  result = CURLE_FAILED_INIT;
188  }
189 
190  return result;
191 }
192 
194 {
195  Curl_safefree(config->trace_dump);
196 
197  if(config->errors_fopened && config->errors)
198  fclose(config->errors);
199  config->errors = NULL;
200 
201  if(config->trace_fopened && config->trace_stream)
202  fclose(config->trace_stream);
203  config->trace_stream = NULL;
204 
205  Curl_safefree(config->libcurl);
206 }
207 
208 /*
209  * This is the main global destructor for the app. Call this after
210  * _all_ libcurl usage is done.
211  */
212 static void main_free(struct GlobalConfig *config)
213 {
214  /* Cleanup the easy handle */
215  curl_easy_cleanup(config->easy);
216  config->easy = NULL;
217 
218  /* Main cleanup */
220  convert_cleanup();
222 #ifdef USE_NSS
223  if(PR_Initialized()) {
224  /* prevent valgrind from reporting still reachable mem from NSRP arenas */
225  PL_ArenaFinish();
226  /* prevent valgrind from reporting possibly lost memory (fd cache, ...) */
227  PR_Cleanup();
228  }
229 #endif
230  free_config_fields(config);
231 
232  /* Free the config structures */
233  config_free(config->last);
234  config->first = NULL;
235  config->last = NULL;
236 }
237 
238 /*
239 ** curl tool main function.
240 */
241 int main(int argc, char *argv[])
242 {
244  struct GlobalConfig global;
245  memset(&global, 0, sizeof(global));
246 
247  main_checkfds();
248 
249 #if defined(HAVE_SIGNAL) && defined(SIGPIPE)
250  (void)signal(SIGPIPE, SIG_IGN);
251 #endif
252 
253  /* Initialize memory tracking */
255 
256  /* Initialize the curl library - do not call any libcurl functions before
257  this point */
258  result = main_init(&global);
259  if(!result) {
260  /* Start our curl operation */
261  result = operate(&global, argc, argv);
262 
263 #ifdef __SYMBIAN32__
264  if(global.showerror)
266 #endif
267 
268  /* Perform the main cleanup */
269  main_free(&global);
270  }
271 
272 #ifdef __NOVELL_LIBC__
273  if(getenv("_IN_NETWARE_BASH_") == NULL)
275 #endif
276 
277 #ifdef __VMS
278  vms_special_exit(result, vms_show);
279 #else
280  return (int)result;
281 #endif
282 }
283 
284 #endif /* ndef UNITTESTS */
#define free(ptr)
Definition: curl_memory.h:130
int main(int argc, char *argv[])
Definition: tool_main.c:241
#define getenv
Definition: setup-vms.h:52
CURL_EXTERN void curl_free(void *p)
Definition: escape.c:239
Definition: ws_ssl.c:25
#define STDERR_FILENO
Definition: tool_main.h:40
static void free_config_fields(struct GlobalConfig *config)
Definition: tool_main.c:193
CURLcode operate(struct GlobalConfig *config, int argc, argv_item_t argv[])
void config_free(struct OperationConfig *config)
Definition: tool_cfgable.c:161
CURLcode
Definition: curl.h:454
struct OperationConfig * last
Definition: tool_cfgable.h:276
bool trace_fopened
Definition: tool_cfgable.h:268
struct GlobalConfig * global
Definition: tool_cfgable.h:251
#define curlx_getenv
Definition: curlx.h:75
#define malloc(size)
Definition: curl_memory.h:124
void helpf(FILE *errors, const char *fmt,...)
Definition: tool_msgs.c:106
UNITTEST_START int result
Definition: unit1304.c:49
static void main_free(struct GlobalConfig *config)
Definition: tool_main.c:212
FILE * trace_stream
Definition: tool_cfgable.h:267
static void main_checkfds(void)
Definition: tool_main.c:83
#define CURL_GLOBAL_DEFAULT
Definition: curl.h:2521
CURL_EXTERN CURL * curl_easy_init(void)
Definition: easy.c:343
CURL_EXTERN void curl_easy_cleanup(CURL *curl)
char * libcurl
Definition: tool_cfgable.h:272
Definition: curl.h:455
CURLcode get_libcurl_info(void)
Definition: tool_libinfo.c:47
#define Curl_safefree(ptr)
Definition: memdebug.h:170
#define STDOUT_FILENO
Definition: tool_main.h:36
CURL_EXTERN CURLcode curl_global_init(long flags)
curl_global_init() globally initializes curl given a bitwise set of the different features of what to...
Definition: easy.c:271
#define convert_cleanup()
Definition: tool_convert.h:41
static CURLcode main_init(struct GlobalConfig *config)
Definition: tool_main.c:138
#define memory_tracking_init()
Definition: tool_main.c:130
char * trace_dump
Definition: tool_cfgable.h:266
#define tool_pressanykey()
Definition: tool_panykey.h:32
#define STDIN_FILENO
Definition: tool_main.h:32
CURL_EXTERN void curl_global_cleanup(void)
curl_global_cleanup() globally cleanups curl, uses the value of "init_flags" to determine what needs ...
Definition: easy.c:312
bool errors_fopened
Definition: tool_cfgable.h:265
void config_init(struct OperationConfig *config)
Definition: tool_cfgable.c:29
struct OperationConfig * first
Definition: tool_cfgable.h:274


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:16