tshark: Fix small memory leak in tap-expert
[metze/wireshark/wip.git] / ui / export_object_ui.c
1 /* export_object_ui.c
2  * Common routines for tracking & saving objects found in streams of data
3  * Copyright 2007, Stephen Fisher (see AUTHORS file)
4  *
5  * Wireshark - Network traffic analyzer
6  * By Gerald Combs <gerald@wireshark.org>
7  * Copyright 1998 Gerald Combs
8  *
9  * SPDX-License-Identifier: GPL-2.0-or-later
10  */
11
12 #include "config.h"
13
14 #include <string.h>
15
16 #include <errno.h>
17
18 #include <glib.h>
19
20 #include <epan/packet_info.h>
21 #include <epan/tap.h>
22
23 #include <wiretap/wtap.h>
24
25 #include <wsutil/file_util.h>
26
27 #include <ui/alert_box.h>
28
29 #include "export_object_ui.h"
30
31 gboolean
32 eo_save_entry(const gchar *save_as_filename, export_object_entry_t *entry, gboolean show_err)
33 {
34     int to_fd;
35     gint64 bytes_left;
36     int bytes_to_write;
37     ssize_t bytes_written;
38     guint8 *ptr;
39     int err;
40
41     to_fd = ws_open(save_as_filename, O_WRONLY | O_CREAT | O_EXCL |
42              O_BINARY, 0644);
43     if(to_fd == -1) { /* An error occurred */
44         if (show_err)
45             open_failure_alert_box(save_as_filename, errno, TRUE);
46         return FALSE;
47     }
48
49     /*
50      * The third argument to _write() on Windows is an unsigned int,
51      * so, on Windows, that's the size of the third argument to
52      * ws_write().
53      *
54      * The third argument to write() on UN*X is a size_t, although
55      * the return value is an ssize_t, so one probably shouldn't
56      * write more than the max value of an ssize_t.
57      *
58      * In either case, there's no guarantee that a gint64 such as
59      * payload_len can be passed to ws_write(), so we write in
60      * chunks of, at most 2^31 bytes.
61      */
62     ptr = entry->payload_data;
63     bytes_left = entry->payload_len;
64     while (bytes_left != 0) {
65         if (bytes_left > 0x40000000)
66             bytes_to_write = 0x40000000;
67         else
68             bytes_to_write = (int)bytes_left;
69         bytes_written = ws_write(to_fd, ptr, bytes_to_write);
70         if(bytes_written <= 0) {
71             if (bytes_written < 0)
72                 err = errno;
73             else
74                 err = WTAP_ERR_SHORT_WRITE;
75             if (show_err)
76                 write_failure_alert_box(save_as_filename, err);
77             ws_close(to_fd);
78             return FALSE;
79         }
80         bytes_left -= bytes_written;
81         ptr += bytes_written;
82     }
83     if (ws_close(to_fd) < 0) {
84         if (show_err)
85             write_failure_alert_box(save_as_filename, errno);
86         return FALSE;
87     }
88
89     return TRUE;
90 }
91
92 /*
93  * Editor modelines
94  *
95  * Local Variables:
96  * c-basic-offset: 4
97  * tab-width: 8
98  * indent-tabs-mode: nil
99  * End:
100  *
101  * ex: set shiftwidth=4 tabstop=8 expandtab:
102  * :indentSize=4:tabSize=8:noTabs=true:
103  */